Establecer la fórmula de columna dinámicamente 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.
Aquí hay una versión simplificada de lo que estoy tratando de lograr en el bucle (he probado muchas variaciones de Expr, Eval, Parse en este código sin éxito):
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
);He leído "Fórmula creada dinámicamente sin evaluación" y otras publicaciones relacionadas, pero me estoy desmoronando. Solo quiero algunos unos o ceros en mi columna de valores atípicos.
Cualquier ayuda o solución será muy apreciada. ¡Gracias de antemano!
Automatización y scriptingRe: Establecer la fórmula de columna dinámicamente con JSLNo estoy 100% seguro de lo que estás intentando hacer, pero esto podría darte algunas ideas.
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: Establecer la fórmula de columna dinámicamente con JSLJMP tiene un tipo de datos de cadena:
a = "gato";
b = "3 + 5";
a y b son cadenas. B parece una expresión, pero no lo es.
c = analizar( b );
c es una expresión, que puede mostrarse como un árbol:
operator(+)
/ \
3 5
c = expr( 3 + 5 ); // es otra forma de obtener la misma expresión almacenada en c
d = eval( c ); // o simplemente d = c; el lado derecho se evalúa de todos modos
d es 8.
A veces, JMP evalúa automáticamente c como 8, a veces no. A veces necesitas 8, a veces necesitas 3+5.
e = nombreexpr(c);
e obtiene la expresión que contiene c; piense en nameexpr como un envoltorio fino; cuando se evalúa el envoltorio, bloquea una evaluación más profunda y devuelve la expresión 3+5, sin evaluar, en lugar de 8.
JMP también tiene un conjunto de funciones para manipular un árbol de expresiones, que no se tratan aquí. @jthi usó substitute, por ejemplo.
Creo que parte de lo que te intriga es la diferencia entre la forma en que las distintas funciones en JSL manejan un argumento de expresión:
cos(c), como la mayoría de funciones, evaluará c como 8. Esto es lo que se espera.
nombre_columna< copia literalmente la expresión (c, no 3+5, no 8) 8) a la fórmula de la columna sin evaluarla. (Tal como lo haría para <
Entonces setformula tiene dos casos especiales :
nombre_columna< c (no especial)
nombre_columna< 8 (envoltorio de evaluación)
nombre_columna< 3+5 (envoltorio de expresión de nombre)
Tenga en cuenta que estos son de hecho casos especiales; setformula hace un esfuerzo adicional para detectar el contenedor eval o nameexpr para que el JSL haga lo que usted espera.
Ahora que casi termino, me gustaría haber usado x+y en lugar de 3+8 para parte de esto; quedaría más claro por qué querrías posponer la evaluación. Además, incluso un solo número como 8 es una expresión; eval(8) es 8.
Re: Establecer la fórmula de columna dinámicamente con JSLGracias por la explicación, tan alucinante como educativa. Creo que la entiendo, al menos conceptualmente.
Supongo que lo descubriré.
Muchas gracias !:)