这似乎是一个很容易解决的问题,但我还是有些困惑。
我有一个包含250行和大约2万列的数据集。这些行分为两类:良好(249行)和不良(1行)。我需要找到所有与“良好”行相比,“不良”行具有更高/更低值的列。
您能建议任何有效的方法吗?
谢谢!
假设您有一列标识1个不良行和249个良好行的所有列,这就是我的操作方法。
1。堆叠所有2万行,保留标识不良行和所有良好行的列
表格==>堆栈
2。汇总结果堆积表
一种。按新列“标签”分组
b。按标识不良和良好数据的列分组
C。指定计算“数据”列的最小值和最大值
3。在结果汇总表中
一种。使用公式添加一个名为“ Min Max”的新列
If(
:Name( "Max(Data,Bad)" ) > :Name( "Max(Data,Good)" ), "Max",
:Name( "Min(Data,Bad)" ) < :Name( "Min(Data,Good)" ), "Min",
"Neither"
)
以下是将创建以上结果的示例脚本。 它使用仅包含4列的示例数据表,但是,通过更改脚本中指向具有不良和不良行的列的名称(在示例数据表中称为“ GoodBad”),它可以为您的20k表工作,到数据表中标识不良和良好数据的列的名称。
该脚本还假定要比较所有数字列。
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)为您提供了一个很好的,易于遵循的解决方案,可以通过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"};