使用 JSL 動態設定列公式I'm working on a JSL script where I need to dynamically build a formula for a given column inside a loop. The idea is to reference a different column for each iteration, so that the formula uses the evaluated column name (e.g., :col_name) rather than inserting the literal code.
這是我在循環中嘗試實現的簡化版本(我在此程式碼中嘗試了 Expr、Eval、Parse 的多種變體,但都無濟於事):
all_cols = dt << Get Column Names();
col = Column(all_cols[N Items(all_cols)-1]); // Changes for every i in the loop
// Dynamically build the formula expression using column names directly
formula = If(
col > :UL_outliers | col < :LL_outliers,
1,
0
);
outlier_col << Set Formula(formula);The problem is that when I set the formula using Set Formula(), instead of dynamically evaluating the column reference, the formula is inserted literally into the column's formula editor. As a result, the column formula is not evaluated and is simply:
If(
col > :UL_outliers | col < :LL_outliers,
1,
0
);我已經閱讀了動態建立公式不評估和其他一些相關文章,但我的思緒卻崩潰了。我只想要我的異常值列中有一些 1 或 0。
任何幫助或解決方法都將不勝感激。先致謝!
自動化和腳本回覆:使用 JSL 動態設定列公式不能 100% 確定你想做什麼,但這可能會給你一些想法
Names Default To Here(1);
dt = open("$SAMPLE_DATA/Big Class.jmp");
dt << new column("LL_outliers", Numeric, Continuous, Set Each Value(50));
dt << new column("UL_outliers", Numeric, Continuous, Set Each Value(70));
all_cols = dt << Get Column Names("Continuous", "String");
colname = all_cols[1];
f_expr = Substitute(
Expr(If(_col_ > :UL_outliers | _col_ < :LL_outliers,
1,
0
)),
Expr(_col_), Name Expr(AsColumn(dt, colname));
);
new_col = dt << New Column("F", Numeric, Nominal);
Eval(EvalExpr(
new_col << Set Formula(Expr(NameExpr(f_expr)));
));回覆:使用 JSL 動態設定列公式JMP 具有字串資料類型:
a = “貓”;
b =“3 + 5”;
a 和 b 是字串。 B 看起來像一個表達式,但實際上不是。
c = 解析(b);
c 是一個表達式,它可以表示為一棵樹:
operator(+)
/ \
3 5
c = expr(3 + 5); // 是另一種取得儲存在 c 中的相同表達式的方法
d = eval(c); // 或僅 d = c;無論如何都會計算右側的值
d 是 8。
有時 JMP 會自動將 c 求值為 8,有時則不會。有時您想要 8,有時您想要 3+5。
e = 名稱表達式(c);
e 取得 c 所持有的表達式;將 nameexpr 視為薄包裝器;當包裝器被評估時,它會阻止更深層的評估並傳回未評估的 3 + 5 表達式,而不是 8。
JMP 還有一組用於操作表達式樹的函數,本文不作介紹。例如, @jthi使用替代品。
我認為您感到困惑的部分是 JSL 中不同函數處理表達式參數的方式之間的差異:
cos(c) 與大多數函數一樣,將計算 c 為 8。
列名< 逐字複製表達式 (c, 不是 3+5, 不是 8 ) 8)而不對列公式進行求值。 (就像<
因此 setformula 有兩種特殊情況:
列名< c (不特殊)
列名< 8(評估包裝器)
列名< 3+5 (nameexpr 包裝器)
請注意,這些確實是特殊情況; setformula 會額外努力偵測 eval 或 nameexpr 包裝器,以使 JSL 依照您的期望執行。
現在我快完成了,我希望我使用 x+y 而不是 3+8 來完成這部分工作;為什麼您可能希望將評估推遲到稍後的時間點,這樣就更加清楚了。而且,即使是像 8 這樣的單一數字也是一種表達式; eval(8) 是 8。
回覆:使用 JSL 動態設定列公式謝謝您令人費解但又很有教育意義的解釋。我想我至少從概念上理解了它。
我想我會找到答案的。
多謝 !:)