如何循环遍历由 2 列创建的组中的行大家好,
我有一个非常简单的问题,但无法从论坛找到确切的答案。 这是我的示例数据表:

基本上它有 4 列,我需要循环遍历从“组 1”和“组 2”生成的每个组合项目,但当且仅当“项目”# 不同时,然后打开“路径”列中的所有文件路径。 例如,在前 2 行中,我们的组合是“aA”,并且由于项目也不同,因此脚本需要打开文件路径 1 和 2。
数据混合和清理回复:如何循环遍历由 2 列创建的组中的行是的,这实际上非常有用。 file_list 变量很令人困惑,因为打开文件并不严格需要它(但是;我认为;它在稍后再次关闭所有文件时很有用(?),例如,或其他一些操作)。 我不得不承认,我也花了一些时间来理解“file_path”变量,该变量在每次迭代时都会分配给不同的文件路径,并且它叫什么并不重要。 (在我看来,我现在只是将其解释为一种工具,从 filepaths_to_open 列表中依次选择一个文件路径,并让用户用它做“某事”。)
谢谢你! 每周增长一点点知识总比什么都没有好。
附: 下面我只能根据我对你的解释的理解来写。 再次强调,非常有用。
Names Default To Here( 1 );
filepaths_to_open = {"$SAMPLE_DATA/Big Class.jmp", "$SAMPLE_DATA/Probe.jmp", "$SAMPLE_DATA/Iris.jmp"};
For Each( {file_path}, filepaths_to_open, Open( file_path ) );
回复:如何循环遍历由 2 列创建的组中的行我认为通过编写演示脚本最容易理解这些(我对 For Each 进行了一些修改以添加 idx,这可能会让它更容易理解它是如何工作的)
Names Default To Here(1);
filepaths_to_open = {"$SAMPLE_DATA/Big Class.jmp", "$SAMPLE_DATA/Probe.jmp", "$SAMPLE_DATA/Iris.jmp"};
show(filepaths_to_open);
file_list = {};
show(file_list);
For Each({file_path, idx}, filepaths_to_open,
show(idx, file_path);
Insert Into(file_list, Open(file_path));
show(file_list);
);
- 我使用 file_list 收集对打开的数据表的引用(我不需要文件路径,因为我已经在 filepaths_to_open 中拥有它们,但我没有引用)
- Open(file_path) 将返回对打开文件的引用,然后 Insert Into 将该引用添加到 file_list。
- {filepath} 来自如何对于每个功能应该使用。 基本上它将循环 filepaths_to_open 并返回 file_path 变量中的每个元素(一一)。
filepaths_to_open = {"$SAMPLE_DATA/Big Class.jmp", "$SAMPLE_DATA/Probe.jmp", "$SAMPLE_DATA/Iris.jmp"};
file_list = {};
idx = 1;
file_path = "$SAMPLE_DATA/Big Class.jmp";
file_list = {DataTable("Big Class")};
idx = 2;
file_path = "$SAMPLE_DATA/Probe.jmp";
file_list = {DataTable("Big Class"), DataTable("Probe")};
idx = 3;
file_path = "$SAMPLE_DATA/Iris.jmp";
file_list = {DataTable("Big Class"), DataTable("Probe"), DataTable("Iris")};
希望能回答一些问题。
回复:如何循环遍历由 2 列创建的组中的行@jthi ,我只是想问几个关于代码最后部分的问题,即我不明白。
file_list = {};
For Each({file_path}, filepaths_to_open,
Insert Into(file_list, Open(file_path));
);
file_list = {};
这是一个空列表。 循环将通过 Insert Into(file_list, Open(file_path)) 填充此内容。 为什么不能只使用 filepaths_to_open 中已包含的列表? 另外,我不明白 Open(file_path) 如何将某些内容插入列表中。 这不就是一个打开文件的函数吗? 这一切如何才能对列表做出贡献呢?
{file_path}这一点,我也想不明白。 这只是实际文件路径的占位符吗?
也许你有解释这些事情的参考资料? 预先非常感谢您。
回复:如何循环遍历由 2 列创建的组中的行您将必须修改 ValidFile 计算,并可能修改行选择,具体取决于构建 ValidFile 检查的方式。
new_col = dt << New Column("ValidFile", Numeric, Continuous, << Set Each Value(
If(Col Sum(1, :g1, :g2, :i) == 1 & Col Number(:i, :g1, :g2) > 1,
1
,
0
);
));回复:如何循环遍历由 2 列创建的组中的行@jthi ,一如既往的整洁。 好好学习,谢谢。
回复:如何循环遍历由 2 列创建的组中的行我设法通过创建另一列“唯一”来找到一个:
new_col = dt << New Column("Unique", Numeric, Continuous, << Set Each Value(
Col Sum(1, :g1, :g2);
));
rows_to_open = dt << Get Rows Where(:ValidFile == 1 & :Unique != 1);
回复:如何循环遍历由 2 列创建的组中的行谢谢jthi! 最后一个问题,如果这些列 g1、g2 和 i 只有 1 个有效文件的组合,我该如何进一步修改公式以忽略?

回复:如何循环遍历由 2 列创建的组中的行编辑我的消息以重命名旧变量。 我们不是将字符列相加,而是通过分组 () 使用它们。 我们使用 1,因此组中的每一行都会增加 1。 通过使用这些函数创建不同类型的公式可能是一个好主意,以便更容易理解它们的工作原理,脚本索引还提供了一些示例。
Col Sum(名称,<按变量,...>)
回复:如何循环遍历由 2 列创建的组中的行嗨,jthi,
感谢您提供如此精彩的答案,并提供了 3 个不同的选项。 附注之一是我必须从 rows_to_open1 变量中删除“1”才能使代码运行。 如果您能更正此拼写错误以供将来参考,那就太好了!
除此之外,我还有一个与你的回答相关的问题。 Col Sum、Col Cumulative Sum 和 Col Max(Col Sum? 中的每一个中的值“1”的目的是什么? 我不明白为什么我们可以对 g1 和 g2 列中的字符值求和?
回复:如何循环遍历由 2 列创建的组中的行嗨雷塞尔,
我已经尝试过你的解决方案,确实打印了正如您提到的,“文件路径6”两次。 我看到的另一个问题是,当我故意将第 5 行项目值从 5 更改为 7 以获得 2 个相同的行时,它会打印最后一行(“文件路径 6”)。 有什么办法可以避免这种情况吗? 我看到 jthi 的替代 for 循环也有同样的问题。


回复:如何循环遍历由 2 列创建的组中的行@雷塞尔
我认为重新考虑循环结构是最简单的,但是您可以使当前的循环结构也按照您想要的方式工作,而无需重复打印:保留已打印内容的列表或找出某种附加逻辑来防止这种情况从发生。 我认为下面的想法应该可行:
For( i = 1, i <= N Items( PairedGroupList ), i++,
dt << Select Where( :PairedGroup == PairedGroupList[i] );
dtTemp = dt << Subset( Invisible, Selected Rows );
For( j = 1, j < N Rows( dtTemp ), j++,
If( dtTemp:item[j] != dtTemp:item[j + 1],
Print(dtTemp:path[j]);
If(j + 1 == N Rows( dtTemp ),
Print(dtTemp:path[j + 1]);
)
)
);
Close( dtTemp, no save );
);
例如,在这里,您不会循环遍历最后一个值,而是检查下一个值是否是最后一个,如果是,则也打印该值(如果您确实打印了当前行)。
回复:如何循环遍历由 2 列创建的组中的行我不确定我是否正确理解了问题,但下面是使用 Col Sum/Col Cumulative Sum 和 Col Max(ColSum()) 的三个不同选项
Names Default To Here(1);
dt = New Table("Untitled",
Add Rows(8),
Compress File When Saved(1),
New Column("g1", Character, "Nominal", Set Values({"a", "a", "a", "a", "a", "c", "c", "c"})),
New Column("g2", Character, "Nominal", Set Values({"A", "A", "B", "B", "B", "A", "A", "A"})),
New Column("i", Numeric, "Continuous", Format("Best", 12), Set Values([1, 3, 2, 4, 4, 5, 7, 9])),
New Column("p",
Character,
"Nominal",
Set Values({"filepath1", "filepath2", "filepath3", "filepath4", "filepath4.1", "filepath5", "filepath6", "filepath7"})
)
);
// depending how we handle duplicated g1+g2+i we would use different formulas
// if we won't open any
new_col = dt << New Column("ValidFile", Numeric, Continuous, << Set Each Value(
Col Sum(1, :g1, :g2, :i);
));
/*
// if we open the first one
new_col = dt << New Column("ValidFile", Numeric, Continuous, << Set Each Value(
Col Cumulative Sum(1, :g1, :g2, :i);
));
*/
/*
// if we don't open g1+g2 at all
new_col = dt << New Column("ValidFile", Numeric, Continuous, << Set Each Value(
Col Max(Col Sum(1, :g1, :g2, :i), :g1, :g2)
));
*/
rows_to_open = dt << Get Rows Where(:ValidFile == 1);
filepaths_to_open = dt[rows_to_open, "p"];
show(filepaths_to_open);
// dt << Delete Column(new_col);
// To open files loop over filepaths_to_open
stop();
file_list = {};
For Each({file_path}, filepaths_to_open,
Insert Into(file_list, Open(file_path));
);

想法是,我们选择 ValidFile 为 1 的行,然后打开这些文件。 该图演示了三个不同公式的计算。
编辑:
修复了旧参考要打开的行1到要打开的行数
回复:如何循环遍历由 2 列创建的组中的行请研究 NChooseK Matrix() 并看看它是否适合您。在脚本索引中,它被描述为: 创建一个由 nChooseK(n,k) 行和 K 列组成的矩阵,形成从 1 到 n 的 k 个整数的所有组合。
我想知道是否可以将其更改为使用字符数据类型?
Names Default To Here( 1 );
Print( NChooseK Matrix( 5, 3 ) );
__________________________
Prints:
[ 1 2 3,
1 2 4,
1 2 5,
1 3 4,
1 3 5,
1 4 5,
2 3 4,
2 3 5,
2 4 5,
3 4 5]
回复:如何循环遍历由 2 列创建的组中的行嗨,下面至少开始了你想做的事情。 您只需更改“打印( dtTemp:路径[j], dtTemp:路径[j + 1] )"部分具有打开文件的功能。
然而不幸的是,按照我编写的方式,该脚本将“文件路径 6”打印两次到日志中,因此如果进行相应修改,它也会打开“文件路径6”两次。 我确信有一种解决方法(例如检查文件路径是否已打开),但现在已经晚了。 不管怎样,如果我也弄清楚如何做剩下的事情,我会让你知道的。 感谢您的反馈!
dt = New Table( "today's challenge",
Add Rows( 7 ),
New Column( "group1",
Character,
"Nominal",
Set Values( {"a", "a", "a", "a", "c", "c", "c"} )
),
New Column( "group2",
Character,
"Nominal",
Set Values( {"A", "A", "B", "B", "A", "A", "A"} ),
Set Display Width( 70 )
),
New Column( "item",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Values( [1, 3, 2, 4, 5, 7, 9] )
),
New Column( "path",
Character,
"Nominal",
Set Selected,
Set Values(
{"file path 1", "file path 2", "file path 3", "file path 4",
"file path 5", "file path 6", "file path 7"}
)
)
);
dt << New Column( "PairedGroup", formula( :group1 || :group2 ) );
PairedGroupList = Associative Array( dt:PairedGroup ) << Get Keys;
dt << Clear Column Selection;
For( i = 1, i <= N Items( PairedGroupList ), i++,
dt << Select Where( :PairedGroup == PairedGroupList[i] );
dtTemp = dt << Subset( Invisible, Selected Rows );
For( j = 1, j <= N Rows( dtTemp ), j++,
If( dtTemp:item[j] != dtTemp:item[j + 1],
Print( dtTemp:path[j], dtTemp:path[j + 1] )
)
);
Close( dtTemp, no save );
);