Cela semble être une question facile à résoudre mais je suis un peu coincé.
J'ai un ensemble de données avec 250 lignes et environ 20K colonnes. Les lignes sont divisées en deux catégories: Bonnes (249 lignes) et Mauvaises (1 ligne). Je dois rechercher toutes les colonnes dans lesquelles la ligne "BAD" a la valeur la plus élevée / la plus basse par rapport au reste des lignes "BON".
Pouvez-vous suggérer un moyen efficace de le faire?
Je vous remercie!
Voici comment je le ferais, en supposant que vous ayez une colonne qui identifie la ligne 1 Bad et toutes les 249 bonnes lignes.
1. Empilez toutes vos 20 000 lignes en conservant la colonne qui identifie la mauvaise ligne et toutes les bonnes lignes.
Tables ==> Pile
2 Résumer la table empilée obtenue
une. Grouper par la nouvelle colonne "Label"
b. Sous-groupe par la colonne qui identifie les données incorrectes et correctes
c. Spécifiez pour calculer le Min et le Max pour la colonne "Données"
3 Dans le tableau récapitulatif résultant
une. Ajouter une nouvelle colonne appelée "Min Max" à l'aide de la formule
If(
:Name( "Max(Data,Bad)" ) > :Name( "Max(Data,Good)" ), "Max",
:Name( "Min(Data,Bad)" ) < :Name( "Min(Data,Good)" ), "Min",
"Neither"
)
Vous trouverez ci-dessous un exemple de script permettant de créer les résultats ci-dessus. Il utilise un exemple de table de données avec seulement 4 colonnes. Toutefois, cela fonctionnera pour votre table de 20 000 $ en modifiant le nom dans le script qui pointe vers la colonne avec les lignes Bad et Good (Appelé "GoodBad" dans le tableau de données Example), au nom de la colonne de votre table de données qui identifie les données incorrectes et correctes.
Le script suppose également que toutes les colonnes numériques doivent être comparées.
Names Default To Here( 1 );
// Create a simple data table for illustration
dt = New Table( "simple",
Add Rows( 10 ),
New Column( "A", Set Values( [59, 61, 55, 66, 52, 60, 61, 51, 60, 61] ) ),
New Column( "B",
Format( "Fixed Dec", 5, 0 ),
Set Values( [22, 123, 74, 145, 64, 84, 128, 79, 112, 107] )
),
New Column( "C",
Set Values( [110, 96, 100, 92, 92, 97, 98, 94, 91, 94] ),
),
New Column( "GoodBad",
Character,
Set Values(
{"Bad", "Good", "Good", "Good", "Good", "Good", "Good", "Good", "Good", "Good"}
)
)
);
// Get All Numeric Columns
numericCols = dt << get column names(numeric);
// Stack all of the numeric
dtStack = dt << Stack(invisible,
columns( numericCols ),
Source Label Column( "Label" ),
Stacked Data Column( "Data" )
);
// Summarize the data
dtSum = dtStack << Summary(
Group( :Label ),
Min( :Data ),
Max( :Data ),
Subgroup( :GoodBad ),
Freq( "None" ),
Weight( "None" ),
Link to original data table( 0 )
);<BR /><BR />// Delete the no longer needed Stacked data table<BR />
<SPAN style="display: inline !important; float: none; background-color: #ffffff; color: #008000; font-family: Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace; font-size: 14px; font-style: normal; font-variant: normal; font-weight: 300; letter-spacing: normal; orphans: 2; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: pre; word-spacing: 0px;">close( dtStack, nosave );</SPAN><BR />// Add the column that determines if Bad column is < or > Good
dtSum << New Column(
"Max or Min",
formula(
If(
:Name( "Max(Data,Bad)" ) > :Name( "Max(Data,Good)" ), "Max",
:Name( "Min(Data,Bad)" ) < :Name( "Min(Data,Good)" ), "Min",
"Neither"
)
)
);
@D_T_M ,
@txnelson , Jim, vous a fourni une bonne solution, facile à suivre, qui peut être réalisée à l’aide de l’interface JMP et des fonctions de colonne. Vous trouverez ci-dessous une solution alternative utilisant JSL et des matrices.
Je ne sais pas quelle approche aurait les meilleures performances. Si vous n'êtes pas familier avec la notation matricielle JMP, ni avec JSL, considérez cette réponse comme une simple info pour les autres utilisateurs de la communauté JMP.
Names Default To Here( 1 );
// Create a simple data table for illustration
dt = New Table( "simple",
Add Rows( 10 ),
New Column( "A", Set Values( [59, 66, 55, 66, 52, 60, 61, 51, 60, 61] ) ),
New Column( "B",
Format( "Fixed Dec", 5, 0 ),
Set Values( [123, 22, 74, 145, 64, 84, 128, 79, 112, 107] )
),
New Column( "C",
Set Values( [96, 110, 100, 92, 92, 97, 98, 94, 91, 94] ),
)
);
cnames = dt << get column names("string"); //need to remove column names that are not to be tested<BR />//typically cnames = cnames[n::n+249999]
//Matrix of bad row - assuming you know which row is bad, row 2.
bmat = dt[2,1::3];
glist = Remove( AsList(1::nrow(dt))[1], 2);
gmax = V Max(dt[ glist, 1::3 ]); //returns a row vector of each column max
gmin = V Min(dt[ glist, 1::3 ]); //returns a row vector of each column min
mxcol = loc(bmat - gmax > 0); //returns a row vector of column # where bmat > gmax
mncol = Loc(bmat - gmin < 0); //returns a row vector of column # where bmat < gmin
HiCol = cnames[transpose(mxcol)];
LoCol = cnames[transpose(mncol)];
show(HiCol, LoCol);
/*:
HiCol = {"C"};
LoCol = {"B"};