A pregunta de aandw acerca de las fórmulas de columna comenzó esta publicación. Si solo usa el editor de fórmulas para crear fórmulas de columna, puede ignorar casi todo esto. Esta publicación trata sobre el uso de JSL para crear una fórmula de columna.
Primero, un poco sobre el comando Fórmula. Aquí hay uno realmente simple:
The formula for column C adds columns A and BThe formula for column C adds columns A and BThe formula for column C adds columns A and BThe formula for column C adds columns A and BLa fórmula para la columna C suma las columnas A y B
La secuencia de comandos de la tabla (triángulo superior izquierdo->copiar secuencia de comandos de la tabla, pegar en un editor) se ve así:
New Table( "abc", Add Rows( 2 ),
New Column( "a", Numeric, "Continuous",Format( "Best", 12 ),Set Values( [1, 7] )),
New Column( "b",Numeric,"Continuous",Format( "Best", 12 ),Set Values( [2, 9] )),
New Column( "c", Numeric, "Continuous", Format( "Best", 12 ),
Formula( :a + :p</img> )
)
)
La línea 5 establece la fórmula; la fórmula es una expresión que suma las columnas a y b. La expresión no se ejecuta hasta mucho más tarde. La expresión se guarda, como expresión, como parte de la columna. Si se agrega otra fila a la tabla o si se cambian los valores de las columnas a o b, la expresión se puede evaluar nuevamente para obtener un valor para la columna c.
Este es un comportamiento amistoso e inusual. Inusual porque la mayoría de las funciones evalúan sus argumentos: sqrt( 4 + 5 ) devuelve 3. Amigable porque casi nunca querrá que JMP evalúe la fórmula de una columna antes de que se asigne a la columna.
A veces, una expresión de fórmula puede ser realmente complicada. Tan complicado que sería más fácil escribir un programa para escribir la expresión. Para hacer eso en el comando de fórmula, necesitaría una forma de decirle al comando de fórmula que evalúe previamente el argumento y use la expresión resultante como fórmula. Lo hace agregando un envoltorio eval() alrededor del código para realizar una evaluación previa. Cuando el comando de fórmula ve "eval" envuelto alrededor de la expresión, ejecuta el código y usa el resultado.
lookup = function({t,u}, expr(a+b) );
New Table( "abc",
Add Rows( 2 ),
New Column( "a",Numeric,"Continuous",Format( "Best", 12 ),Set Values( [1, 7] )),
New Column( "b",Numeric,"Continuous",Format( "Best", 12 ),Set Values( [2, 9] )),
New Column( "c", Numeric, "Continuous", Format( "Best", 12 ),
Formula( eval( lookup(1,2) ) )
)
)
La función de "búsqueda" definida por el usuario (línea 1) no es muy brillante, pero debe ejecutarse para recuperar expr(a+b) como el valor devuelto. En la línea 7, el envoltorio eval() significa que la fórmula de la columna no se establecerá en "lookup(1,2)", sino que se establecerá en la expresión devuelta por lookup(1,2).La misma tabla que antes, con la misma fórmula de columna.
¿Qué sucede si desea que la fórmula de la columna se establezca en una expresión que comience con eval()?¿Cómo podría hacer eso el comando fórmula, ya que comenzar con eval() significa evaluar el argumento y usar el resultado? (Hubiera sido difícil encontrar un ejemplo interesante, pero EM tiene uno en la respuesta de la pregunta.) La respuesta es Name Expr( ). Name Expr es una función JSL que normalmente se usa para obtener una expresión de una variable JSL sin evaluarla. Como el envoltorio más externo en un comando de fórmula, simplemente devuelve el argumento sin evaluarlo. El primer ejemplo podría usarlo, sin ninguna buena razón excepto esta explicación, así, para devolver exactamente la misma tabla:
New Table( "abc", Add Rows( 2 ),
New Column( "a", Numeric, "Continuous",Format( "Best", 12 ),Set Values( [1, 7] )),
New Column( "b",Numeric,"Continuous",Format( "Best", 12 ),Set Values( [2, 9] )),
New Column( "c", Numeric, "Continuous", Format( "Best", 12 ),
Formula( Name Expr( :a + :p</img> ) )
)
)
Pero para EM por ejemplo, es necesario debido al uso inteligente de eval (que probablemente quiera otra publicación de blog para explicar lo que hace). Aquí está la tabla final de la pregunta original. Agregué mi propia idea como una segunda columna de fórmula.
New Table( "final?",Add Rows( 9 ),
New Column( "color",Character,"Nominal",
Set Values({"green", "green", "blue", "yellow", "red", "red", "yellow", "green", "green"})),
New Column( "count",Numeric,"Continuous",Format( "Best", 12 ),
Formula( Name Expr( Eval( Eval Expr( Col Sum( Row() <= Expr( Row() ), :color ) ) ) ) )),
New Column( "another count",Numeric,"Continuous",Format( "Best", 12 ),
Formula(
n = 0;
For( i = 1, i <= Row(), i++,
If( :color == :color[i], n++ )
);
n;
)
)
);
La fórmula de la tercera columna podría ser más rápida, a expensas de la claridad, haciendo que busque la última coincidencia y agregando uno a esa cuenta. La claridad frente a la eficiencia es una compensación.

Entonces, me voy a corregir el error descubierto en este proceso: cuando una tabla de datos crea un script para reproducirse a sí mismo (como el ejemplo superior), tiene que producir JSL para reproducir las fórmulas de las columnas también. En el caso de que la fórmula de la columna comience con el envoltorio especial eval( ), y se supone que eval es parte de la fórmula, JMP necesita agregar el Name Expr.
actualización 21 de abril de 2018: reparación de la conversión automática del blog anterior.