我对 JSL 还很陌生,对编码的了解也非常基础,所以我可能不知道所有正确的术语来描述我的问题,所以我提前道歉。
我想自动执行我经常执行的一个过程,即合并和转换 2 个数据表。我已经有一个可以执行此操作的脚本,但我正在尝试弄清楚如何让 JMP 引用列,而不是对它们进行硬编码,因为列引用可能会发生变化。例如,这是一段代码,它已经执行了我想要的操作,但是是硬编码的:
(Data Table( baselined_dt ) <<
Join(
With( Data Table( main_dt ) ),
Select( :SampleId, :ReplicateId ),
SelectWith(
dlg["data_list"], :ReplicateId // Lets user select columns//
),
Select(
:Dye, :Type, :"1"n, :"2"n, :"3"n, :"4"n, :"5"n, :"6"n, :"7"n, :"8"n, :"9"n,
:"10"n, :"11"n, :"12"n, :"13"n, :"14"n, :"15"n, :"16"n, :"17"n, :"18"n,
:"19"n, :"20"n, :"21"n, :"22"n, :"23"n, :"24"n, :"25"n, :"26"n, :"27"n,
:"28"n, :"29"n, :"30"n, :"31"n, :"32"n, :"33"n, :"34"n, :"35"n, :"36"n,
:"37"n, :"38"n, :"39"n, :"40"n, :"41"n, :"42"n, :"43"n, :"44"n, :"45"n
),
By Matching Columns( :ReplicateId = :ReplicateId ),
Drop multiples( 0, 0 ),
Include Nonmatches( 0, 0 ),
Preserve main table order( 1 )
)) << Set Name( "Joined Data Table" );
问题是 :"#"n 的数量并不总是 1-45,有时可能是 1-40。如果是这种情况,我现在只需在代码中删除 41-45,但我想要一种方法来自动执行此操作,这样我就不必每次都更改代码。我已经能够创建一个包含 {"1"n、"2"n、"3"n 等} 的列表,或者一个包含 {":1", ":2", ":3", 等} 的列表,但我不确定这是否是我想要做的事情所必需的。
本质上,我有限的代码知识认为“Join”函数中的 For 循环可以实现这一点,但我还没有找到让它工作的方法。我甚至不知道“Join”函数中是否可以有 For 循环。我的思维过程让解决方案看起来像这样:
cycle_list = {};
For( i = 1, i <= N Items(cycle_num), i++,
y1 = cycle_num[i];
y2 = (":" || y1);
InsertInto(cycle_list, y2)
);
(Data Table( baselined_dt ) <<
Join(
With( Data Table( main_dt ) ),
Select( :SampleId, :ReplicateId ),
SelectWith(
dlg["data_list"], :ReplicateId // Lets user select columns//
),
Select(
:Dye, :Type,
For( i = 1, i <= N Items( cycle_list ), i++,
cycle_list[i];
);
),
By Matching Columns( :ReplicateId = :ReplicateId ),
Drop multiples( 0, 0 ),
Include Nonmatches( 0, 0 ),
Preserve main table order( 1 )
)) << Set Name( "Joined Data Table" );如果在论坛或脚本索引的某个地方对此有所提及,那么我要么找不到关于它的类似讨论,要么我可能只是不知道如何正确表达我想做的事情。
通常在这种情况下,如果您有列的列表,则可以使用 Eval()
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Trial1.jmp");
dt2 = Open("$SAMPLE_DATA/Little.jmp");
collist = {:popcorn, :oil amt, :batch, :yield};
dt_joined = dt << Join(
With(dt2),
Select(Eval(collist)),
SelectWith(:yield),
By Matching Columns(:popcorn = :popcorn, :batch = :batch, :oil amt = :oil),
Output Table("Join table")
);
如果您有字符串形式的列,它也会起作用(这是我做的方式)
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Trial1.jmp");
dt2 = Open("$SAMPLE_DATA/Little.jmp");
collist = {"popcorn", "oil amt", "batch", "yield"};
dt_joined = dt << Join(
With(dt2),
Select(Eval(collist)),
SelectWith(:yield),
By Matching Columns(:popcorn = :popcorn, :batch = :batch, :oil amt = :oil),
Output Table("Join table")
);
或者通过Name Expr() - 即 kind 或 sqrt( Eval() )
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Trial1.jmp");
dt2 = Open("$SAMPLE_DATA/Little.jmp");
collist = {"popcorn", "oil amt", "batch", "yield"};
dt_joined = dt << Join(
With(dt2),
Select(Name Expr(collist)),
SelectWith(:yield),
By Matching Columns(:popcorn = :popcorn, :batch = :batch, :oil amt = :oil),
Output Table("Join table")
);
嗯,即使Print(collist); collist 也能工作……并且 collist 会被打印出来。因此,似乎参数得到了评估。为什么Select(collist)不起作用?
dt_joined = dt << Join(
With(dt2),
Select(Print(collist);collist),
SelectWith(:yield),
By Matching Columns(:popcorn = :popcorn, :batch = :batch, :oil amt = :oil),
Output Table("Join table")
);
我不知道 Eval 命令。由于我将列作为字符串放在列表中,所以我只需像您一样添加 Eval(cycle_num) 即可!我把解决方案复杂化了。非常感谢您的帮助!