Dies scheint eine einfache Frage zu sein, aber ich stecke irgendwie fest.
Ich habe einen Datensatz mit 250 Zeilen und ungefähr 20.000 Spalten. Die Zeilen sind in zwei Kategorien unterteilt: Gut (249 Zeilen) und Schlecht (1 Zeile). Ich muss alle Spalten finden, in denen die "BAD" -Zeile den höheren / niedrigeren Wert als der Rest der "GOOD" -Zeilen hat.
Können Sie einen effizienten Weg vorschlagen, dies zu tun?
Danke!
Hier ist, wie ich es tun würde, vorausgesetzt, Sie haben eine Spalte, die die 1 Bad-Zeile und alle 249 Good-Zeilen identifiziert.
1. Stapeln Sie alle Ihre 20.000 Zeilen, und behalten Sie dabei die Spalte bei, die die fehlerhafte Zeile und alle guten Zeilen identifiziert
Tabellen ==> Stack
2. Fassen Sie die resultierende gestapelte Tabelle zusammen
ein. Gruppieren nach der neuen Spalte "Label"
b. Untergruppe nach der Spalte, die die fehlerhaften und die fehlerhaften Daten identifiziert
c. Angabe zur Berechnung von Min und Max für die Spalte "Daten"
3. In der resultierenden Übersichtstabelle
ein. Fügen Sie mithilfe der Formel eine neue Spalte mit dem Namen "Min Max" hinzu
If(
:Name( "Max(Data,Bad)" ) > :Name( "Max(Data,Good)" ), "Max",
:Name( "Min(Data,Bad)" ) < :Name( "Min(Data,Good)" ), "Min",
"Neither"
)
Unten finden Sie ein Beispielskript, mit dem die obigen Ergebnisse erstellt werden. Es wird eine Beispieldatentabelle mit nur 4 Spalten verwendet. Für Ihre 20-KB-Tabelle funktioniert dies jedoch, indem der Name im Skript geändert wird, der auf die Spalte mit den Zeilen Bad und Good zeigt (in der Beispieldatentabelle als "GoodBad" bezeichnet). auf den Namen der Spalte in Ihrer Datentabelle, die die fehlerhaften und die fehlerhaften Daten identifiziert.
Das Skript geht auch davon aus, dass alle numerischen Spalten verglichen werden sollen.
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 stellte Ihnen eine gute, leicht zu verfolgende Lösung zur Verfügung, die mit der JMP-Benutzeroberfläche und den Spaltenfunktionen durchgeführt werden kann. Unten finden Sie eine alternative Lösung mit JSL und Matrizen.
Ich bin mir nicht sicher, welcher Ansatz die beste Leistung bringen würde. Wenn Sie weder mit JMP-Matrixnotation noch mit JSL vertraut sind, betrachten Sie diese Antwort nur als Hinweis für andere in der JMP-Community.
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"};