选择与同一表中另一列中的条件匹配的列的更好方法?这篇文章末尾的脚本基本上做了我想要它做的事情(即,查找时间 = 0 时 Y 值为 100 的列),但它也会生成一条日志消息,这让我有点不舒服(已经踩了之前陷入陷阱):
A message with an empty Boolean argument enabled an option that was already enabled. That option remains enabled. In previous versions of JMP, this would have disabled the option.
在作为循环构造的一部分被选择一次之后,此消息将打印到再次选择的每一列的日志中。 作为一个相对较新的脚本编写新手,我主要担心两个问题:
- 我绝对应该避免这条日志消息吗?我会遇到麻烦吗? 我最终将处理更大的表,因此对于单个脚本执行,此日志消息可能会打印数百次。
- 是否有更智能的方法来查找表中每行时间 = 0 且 Y 值 = 100 的所有列? (就我而言,我将处理包含许多列的表,其中一些列包含在时间 =0 时标准化为 100% 相对值的结果。 这些是我感兴趣的专栏。)
Names Default To Here( 1 );
// table required for example
dt = New Table( "Results (absolute & relative) vs time",
Add Rows( 8 ),
New Column( "time",
Numeric,
Set Values( [0, 1, 2, 3, 0, 1, 2, 3] ),
),
New Column( "Y1_absolute",
Numeric,
Set Values( [7, 8, 1, 9, 0.2, 0.4, 0.65, 0.98] ),
),
New Column( "Y1-relative",
Numeric,
Set Values( [100, 114, 14, 129, 100, 200, 325, 490] ),
),
New Column( "Y2_absolute",
Numeric,
Set Values( [12, 6, 4, 0, 80, 90, 120, 75] ),
),
New Column( "Y2_relative",
Numeric,
Set Values( [100, 50, 33, 0, 100, 113, 150, 94] ),
)
);
// selecting columns where for :time == 0 a Y-value == 100 is found
For( i = 1, i <= N Row( dt ), i++,
For( j = 1, j <= N Col( dt ), j++,
If( Column( j )[i] == 0,
For( k = 1, k <= N Col( dt ), k++,
If( Column( k )[i] == 100,
Column( k ) << Set Selected
)
)
)
)
);
分享和交流结果回复:选择与同一表中另一列中的条件匹配的列的更好方法?FWIW,这避免了子集表,但可能不会快得多:
Names Default To Here( 1 );
// table required for example
dt = New Table( "Results (absolute & relative) vs time",
Add Rows( 8 ),
New Column( "time",
Numeric,
Set Values( [0, 1, 2, 3, 0, 1, 2, 3] ),
),
New Column( "Y1_absolute",
Numeric,
Set Values( [7, 8, 1, 9, 0.2, 0.4, 0.65, 0.98] ),
),
New Column( "Y1-relative",
Numeric,
Set Values( [100, 114, 14, 129, 100, 200, 325, 490] ),
),
New Column( "Y2_absolute",
Numeric,
Set Values( [12, 6, 4, 0, 80, 90, 120, 75] ),
),
New Column( "Y2_relative",
Numeric,
Set Values( [100, 50, 33, 0, 100, 113, 150, 94] ),
)
);
// Rows that have time = 0
r0 = dt << getRowsWhere(:time == 0);
// Loop over other columns (assumes time is in the first column)
for(c=2, c<=NCol(dt), c++,
if(Contains(Column(dt, c)[r0], 100), Column(dt, c) << setSelected(1));
);
回复:选择与同一表中另一列中的条件匹配的列的更好方法?再次感谢你。 子集设置确实提高了我真实(大)表的性能。 下面发布了改进的解决方案。 我之前就考虑过这个问题,但显然需要短暂的休息才能到达那里。 但我什至没有考虑到构建列列表并迭代删除项目。 也谢谢你!
Names Default To Here( 1 );
// new table required for example
dt = New Table( "Results (absolute & relative) vs time",
Add Rows( 8 ),
New Column( "time",
Numeric,
Set Values( [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3] ),
),
New Column( "Y1_absolute",
Numeric,
Set Values( [7, 8, 1, 9, 0.2, 0.4, 0.65, 0.98, 0.7, ., 0.83, 0.4] ),
),
New Column( "Y1-relative",
Numeric,
Set Values( [100, 114, 14, 129, ., 200, 325, 490, 100, 330, 540, 213] ),
),
New Column( "Y2_absolute",
Numeric,
Set Values( [12, 6, 4, 0, 80, 90, 120, 75, 8.3, 9.7, 6.4, 5.2] ),
),
New Column( "Y2_relative",
Numeric,
Set Values( [., 50, 33, 0, 100, 113, 150, 94, 100, 66, 37, 12] ),
)
);
// finding and selecting Y columns where for any :time == 0 a value of 100 is found in the same row
dt << Select Where( dt:time == 0 );
dtTemp = dt << Subset ( Selected Rows, Selected Columns Only( 0 ) );
For( i = 1, i <= N Row( dtTemp ), i++,
For( j = 1, j <= N Col( dtTemp ), j++,
If( Column( dtTemp, j )[i] == 100,
Column( dt, j ) << Set Selected( 1 ),
)
)
);
Close( dtTemp, no save );
dt << Clear Select( );
回复:选择与同一表中另一列中的条件匹配的列的更好方法?一些想法:
在继续循环之前,您可以尝试在 time=0 上对表进行子集化。 这将解压 for 循环的一层。
您可以构建一个列列表并删除您选择的列。 然后,对于下一次迭代,您只需循环遍历剩余的未选择的列。
回复:选择与同一表中另一列中的条件匹配的列的更好方法?非常感激! 我想我会进一步编辑该循环。
- 一旦确定了正确的列,就没有理由遍历整个表。 (编辑:以我目前的技能水平来说,这可能有点困难。 不同的 Y 列可能在不同的行中有缺失值。 我需要找到时间 = 0 与一个或多个 Y 值 = 100 匹配的所有 Y 列。)
- 为什么要循环遍历所有行,而不仅仅是时间实际上为零的行?
编辑:坚持提出的解决方案。 看起来很健壮,不想再花更多时间了。 但第二点,即不循环遍历表的所有行,是我应该并且可能会在某个时候考虑的问题。
回复:选择与同一表中另一列中的条件匹配的列的更好方法?在 << set selected 之后添加 (1) 可以处理错误消息。 您不是切换它,而是定义您想要的最终状态:
For( i = 1, i <= N Row( dt ), i++,
For( j = 1, j <= N Col( dt ), j++,
If( Column( j )[i] == 0,
For( k = 1, k <= N Col( dt ), k++,
If( Column( k )[i] == 100,
Column( k ) << Set Selected(1)
)
)
)
)
);