これは簡単に解決できる質問のように思えますが、私はちょっと立ち往生しています。
250行と約20K列のデータセットがあります。行は、良い(249行)と悪い(1行)の2つのカテゴリに分けられます。「BAD」行が他の「GOOD」行と比較して高い/低い値を持つすべての列を見つける必要があります。
これを行うための効率的な方法を提案できますか?
ありがとうございました!
1行の悪い行と249行のすべての良い行を識別する列があると仮定して、これをどのように行うかを示します。
1。すべての2万行をスタックし、悪い行とすべての良い行を識別する列を維持します
テーブル==>スタック
2。結果のスタックテーブルを要約します。
a。新しい列「ラベル」でグループ化
b。悪いデータと良いデータを識別する列ごとのサブグループ
c。列「データ」の最小値と最大値を計算するために指定します
3。結果の概要テーブル
a。式を使用して「最小最大」という新しい列を追加します
If(
:Name( "Max(Data,Bad)" ) > :Name( "Max(Data,Good)" ), "Max",
:Name( "Min(Data,Bad)" ) < :Name( "Min(Data,Good)" ), "Min",
"Neither"
)
上記の結果を作成するスクリプトの例を以下に示します。 4列のみのサンプルデータテーブルを使用しますが、悪い行と良い行の列を指すスクリプトの名前を変更することで、20kテーブルで機能します(例のデータテーブルでは「GoodBad」と呼ばれます)。悪いデータと良いデータを識別するデータテーブルの列の名前。
スクリプトは、すべての数値列が比較されることも想定しています。
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 、
しゅう 、Jimは、JMPインターフェースと列関数を使用して実行できる優れた、わかりやすいソリューションを提供しました。 以下は、JSLとマトリックスを使用した代替ソリューションです。
どのアプローチが最高のパフォーマンスを発揮するかはわかりません。JMPマトリックス表記やJSLに慣れていない場合は、この応答を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"};