Sembra una domanda facile da risolvere ma sono un po 'bloccato.
Ho un set di dati con 250 righe e circa 20.000 colonne. Le righe sono divise in due categorie: Buono (249 righe) e Cattivo (1 riga). Devo trovare tutte le colonne in cui la riga "BAD" ha il valore più alto / più basso rispetto al resto delle righe "GOOD".
Puoi suggerire un modo efficace per farlo?
Grazie!
Ecco come lo farei, supponendo che tu abbia una colonna che identifica la riga 1 Bad e tutte le 249 righe Good.
1. Impila tutte le tue 20k righe, mantenendo la colonna che identifica la riga Bad e tutte le righe Good
Tabelle ==> Pila
2. Riassumi la tabella Stacked risultante
un. Raggruppa per la nuova colonna "Etichetta"
b. Sottogruppo per colonna che identifica i dati Bad and Good
c. Specificare per calcolare Min e Max per la colonna "Dati"
3. Nella tabella di riepilogo risultante
un. Aggiungi una nuova colonna denominata "Min max" utilizzando la formula
If(
:Name( "Max(Data,Bad)" ) > :Name( "Max(Data,Good)" ), "Max",
:Name( "Min(Data,Bad)" ) < :Name( "Min(Data,Good)" ), "Min",
"Neither"
)
Di seguito è riportato uno script di esempio che creerà i risultati di cui sopra. Utilizza una tabella di dati di esempio con solo 4 colonne, tuttavia, funzionerà per la tua tabella 20k modificando il nome nello script che punta alla colonna con le righe Bad e Good (chiamato "GoodBad" nella tabella dei dati di esempio), al nome della colonna nella tabella dei dati che identifica i dati errati e positivi.
Lo script presuppone inoltre che tutte le colonne numeriche debbano essere confrontate.
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, ti ha fornito una soluzione valida e facile da seguire che può essere eseguita con l'interfaccia JMP e le funzioni della colonna. Di seguito è una soluzione alternativa che utilizza JSL e matrici.
Non sono sicuro di quale approccio avrebbe le migliori prestazioni. Se non si ha familiarità con la notazione della matrice JMP, né JSL, considerare questa risposta solo un FYI per gli altri nella comunità 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"};