使用 expr() 替换公式中的变量列名我尝试创建嵌套循环:
第一个循环创建一些列并包含公式
第二个循环创建一些其他列,公式将需要第一个循环中的列
我的问题是在第二个循环中,我无法使用 eval() + substitue() + expr() 正确设置公式中的列名称
Names Default To Here( 1 );
dt = current data table();
a=3;
b=3;
alist = {1,2,3};
blist = {1,2,3};
// In actual script, above numbers will come from H list box input
For (i=1, i <= a, i++,
dt << New Column( eval("a_" || char(alist[i])), Formula(:gap*2) );
col = "a_" || char(alist[i]);
For (k=1, k <= b, k++,
eval(
substitute(
Expr(
dt << New Column( eval("a_" || char(alist[i]) || " b_" || char(blist[k])), Formula( If(:vvv > 0 & (:vvv < blist[k] ),1,0) ) );
),
Expr(vvv),
col //here gives wrong result, the formula doesn't really use column a_1, a_2, a_3, instead it use "a_1"......etc
)
)
)
)
自动化和脚本编写回复:使用 expr() 替换公式中的变量列名称这可能会给一些想法
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
a = 3;
b = 3;
alist = {1, 2, 3};
blist = {1, 2, 3};
// In actual script, above numbers will come from H list box input
For(i = 1, i <= a, i++,
new_col = dt << New Column(Eval("a_" || Char(alist[i])), Formula(:height* 2));
For(k = 1, k <= b, k++,
Eval(Substitute(
Expr(dt << New Column("a_" || char(new_col << get name) || " b_" || char(blist[k]),
Formula(If(vvv > 0 & (vvv < www), 1, 0))
)),
Expr(vvv), Name Expr(AsColumn(new_col)),
Expr(www), blist[k]
)
)
);
);
编辑:
如果您有 JMP16+,您可以将循环更改为 For Each (这也使用 Eval(EvalExpr()) 而不是 Eval(Substitute()),因为在我看来,在像这样的简单情况下它更清楚
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
alist = {1, 2, 3};
blist = {1, 2, 3};
For Each({aval}, alist,
new_col = dt << New Column("a_" || Char(aval), Formula(:height * 2));
For Each({bval}, blist,
col_title = "a_" || Char(new_col << get name) || " b_" || Char(bval);
Eval(EvalExpr(
dt << New Column(col_title, Numeric, Nominal, Formula(
If(0 < Expr(Name Expr(As Column(dt, new_col))) < Expr(bval),
1
,
0
)
))
));
);
);
回复:使用 expr() 替换公式中的变量列名称这解决了我的问题,谢谢。 第二种方法看起来更清晰
还有一个问题,我在代码中直接使用blist[k],你使用“www”然后替换它。 两者给出相同的计算结果
是否因为我的方法会在公式中留下一个变量 blist[k] ,如果用户在代码执行后尝试再次应用公式,该变量可能会出错?
回复:使用 expr() 替换公式中的变量列名简短回答:
是的。 如果您丢失了对 blist 或 k 的引用,则公式无法重新计算。 如果在您仍然可以访问这两个公式时重新评估公式,相同的k 将用于所有会产生错误答案的公式。 您应该能够通过运行来测试这一点dt << 重新运行公式;
查看更多...
长答案:
是的,如果您不评估它们,它会将 blist[k] 留在您的数据表中。 这将是您在所有公式中拥有的最后一个 k 值(如果在仍然有权访问 blist 和 k 的情况下重新评估公式,则会出现问题)并且如果重新打开表(或者由于某种原因您无法访问 blist / k)那些根本不存在。 这类情况通常可以通过检查公式轻松验证


另一个容易发生这种情况的地方是图形脚本,您可以类似地从图形脚本窗口中看到它们</CODE></P>
<P> </P>
<PRE><CODE class=" language-jsl">Names Default To Here(1);
dt = open("$SAMPLE_DATA/Big Class.jmp");
gb = dt << Graph Builder(
Variables(X(:weight), Y(:height), Overlay(:sex)),
Elements(Points(X, Y, Legend(9)), Line Of Fit(X, Y, Legend(11)))
);
line = 60;
framebox = Report(gb)[frame box(1)];
framebox << Add Graphics Script(
H Line(line)
);
line = 70;
framebox << Add Graphics Script(
H Line(line)
);
你将有两个像这样的脚本

Y = 60 上不会有线。 此外,如果您复制图形生成器脚本,它将在那里显示线条而不是值
Graph Builder(
Variables(X(:weight), Y(:height), Overlay(:sex)),
Elements(Points(X, Y, Legend(9)), Line Of Fit(X, Y, Legend(11))),
SendToReport(
Dispatch(
{},
"Graph Builder",
FrameBox,
{Add Graphics Script(9, Description(""), H Line(line)),
Add Graphics Script(10, Description(""), H Line(line))}
)
)
)
解决这个问题的简单方法是评估这些值
Names Default To Here(1);
dt = open("$SAMPLE_DATA/Big Class.jmp");
gb = dt << Graph Builder(
Variables(X(:weight), Y(:height), Overlay(:sex)),
Elements(Points(X, Y, Legend(9)), Line Of Fit(X, Y, Legend(11)))
);
line = 60;
framebox = Report(gb)[frame box(1)];
Eval(EvalExpr(
framebox << Add Graphics Script(
H Line(Expr(line))
);
));
line = 70;
Eval(EvalExpr(
framebox << Add Graphics Script(
H Line(Expr(line))
);
));
更一般地说,我想说,如果您开始通过将变量名称评估为值来替换变量名称,那么有时评估所有变量可能是一个好主意。 在这种情况下,我的意思是,评估列标题也可能是有益的
Eval(EvalExpr(
dt << New Column(Expr(col_title), Numeric, Nominal, Formula(
If(0 < Expr(Name Expr(As Column(dt, new_col))) < Expr(bval),
1
,
0
)
))
));
);
例如,当您调试代码时,这会带来额外的好处。 下面是从引用创建列并使用一个可以正常工作的变量的简单示例
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
new_col = dt << New Column("Test", Numeric, Continuous, << Set Each Value(1));
col_title = (new_col << get name) || "* var";
var = 2;
Eval(EvalExpr(
dt << New Column(col_title, Numeric, Nominal, Formula(
Expr(NameExpr(AsColumn(dt, new_col))) * Expr(var)
));
));
但如果您遇到一些问题,您可以突出显示 EvalExpr() 及其内部的所有内容并运行脚本的该部分

col_title 未被评估(在这种情况下不是问题,但如果您有更复杂的脚本,则可能会出现问题),只需添加(在这种情况下)一个 Expr() 您将获得更多信息,了解到底发生了什么

回复:使用 expr() 替换公式中的变量列名称感谢您提供如此详细的信息,我可以理解您的观点,我将修改我的代码作为您的示例