Définir la formule de colonne de manière dynamique avec 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.
Voici une version simplifiée de ce que j'essaie de réaliser dans la boucle (j'ai essayé de nombreuses variantes de Expr, Eval, Parse dans ce code sans succès) :
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
);J'ai lu « Formule créée dynamiquement non évaluée » et d'autres articles similaires, mais je suis perdu. Je veux juste des 1 ou des 0 dans ma colonne des valeurs aberrantes.
Toute aide ou solution serait grandement appréciée. Merci d'avance !
Automatisation et scriptsRe : Définir la formule de colonne de manière dynamique avec JSLJe ne suis pas sûr à 100 % de ce que vous essayez de faire, mais cela pourrait donner quelques idées
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 : Définir la formule de colonne de manière dynamique avec JSLJMP a un type de données de chaîne :
a = "chat";
b = "3 + 5";
a et b sont des chaînes de caractères. B ressemble à une expression, mais n'en est pas une.
c = analyser( b );
c est une expression qui peut être représentée sous forme d'arbre :
operator(+)
/ \
3 5
c = expr( 3 + 5 ); // est une autre façon d'obtenir la même expression stockée en c
d = eval( c ); // ou simplement d = c ; le côté droit est évalué de toute façon
d est 8.
Parfois, JMP évalue automatiquement c à 8, parfois non. Parfois, vous voulez 8, parfois 3+5.
e = nomexpr(c);
e obtient l'expression que c contient ; considérez nameexpr comme un wrapper mince ; lorsque le wrapper est évalué, il bloque une évaluation plus approfondie et renvoie l'expression 3+5, non évaluée, plutôt que 8.
JMP dispose également d'un ensemble de fonctions permettant de manipuler un arbre d'expression, non abordé ici. @jthi a utilisé substitute, par exemple.
Je pense qu'une partie de ce qui vous intrigue est la différence entre la façon dont différentes fonctions dans JSL géreront un argument d'expression :
cos(c) , comme la plupart des fonctions, évaluera c à 8. C'est ce à quoi vous vous attendez.
nom de colonne< copie littéralement l'expression (c, pas 3+5, pas 8 ) 8) à la formule de la colonne sans l'évaluer. (Tout comme ce serait le cas pour <
Ainsi, setformula a deux cas particuliers :
nom de colonne< c (pas spécial)
nom de colonne< 8 (wrapper d'évaluation)
nom de colonne< 3+5 (encapsuleur nameexpr)
Notez qu'il s'agit en effet de cas particuliers ; setformula fait un effort supplémentaire pour détecter le wrapper eval ou nameexpr pour que le JSL fasse ce que vous attendez.
Maintenant que j'ai presque terminé, j'aurais préféré utiliser x+y plutôt que 3+8 pour une partie de ceci ; cela expliquerait mieux pourquoi il serait judicieux de reporter l'évaluation à une date ultérieure. De plus, même un nombre unique comme 8 est une expression ; eval(8) vaut 8.
Re : Définir la formule de colonne de manière dynamique avec JSLMerci pour cette explication déroutante mais très instructive. Je crois que je la comprends, au moins conceptuellement.
Je suppose que je le découvrirai.
Merci beaucoup !:)