使用 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() 取代公式中的變數列名稱感謝您提供如此詳細的信息,我可以理解您的觀點,我將修改我的程式碼作為您的範例