Imposta la formula della colonna in modo dinamico con JSLI'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.
Ecco una versione semplificata di ciò che sto cercando di ottenere nel ciclo (ho provato numerose varianti di Expr, Eval, Parse in questo codice, ma senza successo):
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
);Ho letto Formula creata dinamicamente e non valutata e altri post correlati, ma la mia mente si sta sciogliendo. Voglio solo qualche 1 o 0 nella mia colonna outlier.
Qualsiasi aiuto o soluzione alternativa sarebbe molto apprezzato. Grazie in anticipo!
Automazione e scriptingRe: Imposta la formula della colonna in modo dinamico con JSLNon sono sicuro al 100% di cosa stai cercando di fare, ma questo potrebbe darti qualche idea
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)));
));Re: Imposta la formula della colonna in modo dinamico con JSLJMP ha un tipo di dati stringa:
a = "gatto";
b = "3 + 5";
a e b sono stringhe. B sembra un'espressione, ma non lo è.
c = analizza( b );
c è un'espressione che può essere rappresentata come un albero:
operator(+)
/ \
3 5
c = expr( 3 + 5 ); // è un altro modo per ottenere la stessa espressione memorizzata in c
d = eval( c ); // o semplicemente d = c; il lato destro viene comunque valutato
d è 8.
A volte JMP valuterà automaticamente c a 8, a volte no. A volte vuoi 8, a volte vuoi 3+5.
e = nomeespressione(c);
e ottiene l'espressione contenuta in c; si pensi a nameexpr come a un wrapper sottile; quando il wrapper viene valutato, blocca una valutazione più approfondita e restituisce l'espressione 3+5, non valutata, anziché 8.
JMP dispone anche di una serie di funzioni per manipolare un albero di espressioni, non trattate qui. @jthi ha utilizzato substitute, ad esempio.
Penso che parte di ciò che ti sta creando confusione sia la differenza tra il modo in cui diverse funzioni in JSL gestiscono un argomento di espressione:
cos(c), come la maggior parte delle funzioni, valuterà c a 8. Questo è ciò che ti aspetti.
nomecolonna< copia letteralmente l'espressione (c, non 3+5, non 8) 8) alla formula della colonna senza valutarla. (Proprio come farebbe per <
Quindi setformula ha due casi speciali :
nomecolonna< c (non speciale)
nomecolonna< 8 (involucro di valutazione)
nomecolonna< 3+5 (involucro nameexpr)
Si noti che questi sono effettivamente casi speciali; setformula compie uno sforzo extra per rilevare il wrapper eval o nameexpr per far sì che JSL faccia ciò che ci si aspetta.
Ora che ho quasi finito, vorrei aver usato x+y anziché 3+8 per parte di questo; sarebbe più chiaro perché potresti voler posticipare la valutazione a un momento successivo. Inoltre, anche un singolo numero come 8 è un'espressione; eval(8) è 8.
Re: Imposta la formula della colonna in modo dinamico con JSLGrazie per la spiegazione sconvolgente ma molto educativa. Credo di averla capita almeno concettualmente.
Immagino che lo scoprirò.
Molte grazie !:)