Inserte una expresión en otra usando Eval Insert, Eval Expr, Parse y SubstituteProblemaNecesitas insertar el valor de una variable. en una expresión sin evaluar todo el código.Ejemplos incluyen:
- Escribir fórmulas de columnas usando un script
- Escribir guiones usando otro guión
A continuación se muestra un script para transformar las columnas seleccionadas en una tabla. Esto hace NO funciona, porque la expresión 'cols[i]' se guarda en la fórmula de la columna en lugar del nombre de la columna.
//Open A Table and select a few columns
dt = Open( "$Sample_data/iris.jmp" );
cols = {Sepal length, Petal length};
//This code does not work
For( i = 1, i <= N Items(cols), i++,
dt << New Column(
"2 * " || Char( cols[i] ),
Numeric,
"Continuous",
Formula( As Column( cols[i] ) * 2)
)
);
Se crean nuevas columnas con el nombre correcto pero con esta fórmula:

Solución
Hay dos estrategias generales para resolver esto: construir la expresión mientras se evalúa una parte de ella antes que el resto, y construir la expresión como una cadena y luego evaluarla. Tenga en cuenta que la variable que se inserta puede ser en realidad una expresión de cualquier longitud.
Expresiones
Estos métodos implican escribir una expresión y evaluar una parte de ella antes que el resto. Puede resultar complicado encontrar la combinación correcta de Eval, Eval Expr y Expr, pero puede ver el resaltado de sintaxis y utilizar el editor de scripts para asegurarse de que los paréntesis coincidan.
Evaluación, Evaluación Expr
Escriba la expresión y ajuste cualquier parte que deba evaluarse inmediatamente con Expr():
//Eval Expr
For( i = 1, i <= N Items(cols), i++,
Eval( Eval Expr(
dt << New Column(
"2 * " || Char( cols[i] ),
Numeric,
"Continuous",
Formula( As Column( Expr( Char( cols[i] ) ) ) * 2)
)
) )
);
Sustituto
Escriba la expresión y reemplace parte de ella con código evaluado:
//Substitute
For( i = 1, i <= N Items(cols), i++,
Eval( Substitute(
Expr( dt << New Column(
"2 * " || cn,
Numeric,
"Continuous",
Formula( As Column( cn ) * 2)
) ),
Expr( cn ),
Char( cols[i] )
) )
);
Métodos de cadena
Estos métodos implican escribir la expresión como una cadena, usar Parse() para convertirla en una expresión y luego Eval() para evaluarla. Las desventajas de estos métodos incluyen no ver ningún resaltado de sintaxis, la necesidad de manejar comillas dobles usando \!" o \[... ]\ y, en general, ser difíciles de solucionar o modificar en el futuro, especialmente para expresiones largas.
Insertar evaluación
Escriba la expresión como una cadena con código 'en línea' que se evalúa y se coloca dentro de la cadena, luego analícela y evalúela:
//Eval Insert
For( i = 1, i <= N Items(cols), i++,
Eval( Parse( Eval Insert(
"\[dt << New Column(
"2 * ^Char( cols[i] )^",
Numeric,
"Continuous",
Formula( As Column( "^Char( cols[i] )^" ) * 2)
)]\"
) ) );
);
Sustituto
Escriba la expresión en una cadena con un marcador de posición que se reemplaza con la expresión evaluada. Tenga en cuenta que esta es la misma función que la anterior:
//Substitute
For( i = 1, i <= N Items(cols), i++,
Eval( Parse( Substitute(
"\[dt << New Column(
"2 * ColumnName",
Numeric,
"Continuous",
Formula( As Column( "ColumnName" ) * 2)
)]\",
"ColumnName",
Char( cols[i] )
) ) );
);
Concatenar
La forma más básica, escribe la expresión usando '||'.Tenga en cuenta que puede utilizar \[ ... ]\ en lugar de \!":
//Concatenate
For( i = 1, i <= N Items(cols), i++,
Eval( Parse(
"dt << New Column(
\!"2 * " || Char( cols[i] ) || "\!",
Numeric,
\!"Continuous\!",
Formula( As Column( \!"" || Char( cols[i] ) || "\!" ) * 2)
)"
) );
);
Ver también
La sección 'Funciones de manejo de expresiones' de la Guía de secuencias de comandos incluye estos y otros métodos para lograr lo mismo.Esta publicación de blog por @Joseph Morgan tiene ejemplos adicionales e ideas sobre el mismo tema.
Gracias @Justin_Chilton para recibir comentarios sobre esta publicación.
Insertar variables o expresiones en otras expresiones.Esta es una breve introducción a Eval(), Eval Expr(), Substitute(), Parse() y Eval Insert().
Re: Insertar una expresión dentro de otra usando Eval Insert, Eval Expr, Parse y SubstituteA continuación se muestra un ejemplo de un método de expresión y un método de cadena:
Names default to here(1);
//Open A Table and select a few columns
dt = Open( "$Sample_data/iris.jmp" );
cols = {Sepal length, Petal length};
//Eval Expr
For( i = 1, i <= N Items(cols), i++,
Eval( Eval Expr(
dt << New Column(
"Eval Expr 2 * " || Char( cols[i] ),
Numeric,
"Continuous",
Formula( Expr( cols[i] ) * 2 )
)
) )
);
//Substitute with String
For( i = 1, i <= N Items(cols), i++,
Eval( Parse( Substitute(
"\[dt << New Column(
"Substitute String 2 * ColumnName",
Numeric,
"Continuous",
Formula( :"ColumnName"n * 2)
)]\",
"ColumnName",
Char( cols[i] )
) ) );
);
Re: Insertar una expresión dentro de otra usando Eval Insert, Eval Expr, Parse y SubstituteEsto podría tener algunas funciones innecesarias allí, pero puede usar Name Expr con referencia de columna (Como columna (nombre)):
Names Default To Here(1);
//Open A Table and select a few columns
dt = Open("$Sample_data/iris.jmp");
cols = {Sepal length, Petal length};
For(i = 1, i <= N Items(cols), i++,
Eval(Eval Expr(dt << New Column("2 * " || Char(cols[i]), Numeric, "Continuous", Formula(Expr(Name Expr(As Column(Char(cols[i])))) * 2))))
);
Re: Insertar una expresión dentro de otra usando Eval Insert, Eval Expr, Parse y Substitute¿Hay alguna forma en la que no se necesite As Column()?
Aquí necesitamos incluirlo ya que estamos pasando una cadena, me pregunto cómo hacerlo para que la fórmula quede con: columna.
Re: Insertar una expresión dentro de otra usando Eval Insert, Eval Expr, Parse y Substitute¡Muchas gracias! Sí. Tienes razón con el inicio del bucle. No me di cuenta de eso.
Re: Insertar una expresión dentro de otra usando Eval Insert, Eval Expr, Parse y Substitute@Bisoño ,
El bucle for comienza con i=2, es por eso que se saltó la primera columna y se creó una sola columna en blanco llamada Columna 1 cuando se creó la tabla de datos. Puedes 'arreglar' esto iniciando el ciclo con i=1 y eliminando la Columna 1 después, así:
Ver más... Re: Insertar una expresión dentro de otra usando Eval Insert, Eval Expr, Parse y SubstituteHola,
funcionó para las columnas b y c. "a" no aparece. En su lugar, aparece una columna 1 vacía.
Por eso intenté poner el "bucle for" dentro de la Nueva Tabla (). Pero luego, con este enfoque, obtengo solo la expresión dentro de la fórmula.
¿Sabe cómo manejar el "bucle for" con la fórmula dentro de New Table() para obtener todas las columnas requeridas a la vez?
Re: Insertar una expresión dentro de otra usando Eval Insert, Eval Expr, Parse y SubstituteHola @Bisoño ,
Debe decirle a JMP que evalúe esa expresión antes de ponerla en la fórmula, ya que una vez en una fórmula de columna ya no sabe cómo hacer referencia a su otra tabla. Usando mi método preferido (el de arriba), podría verse así:
Names Default To Here( 1 ); //
//Table with columns you want to create
mydt = New Table( "Source",
Add Rows( 3 ),
New Column( "Name", Character, "Nominal", Set Values( {"a", "b", "c"} ) ),
New Column( "Mean", Numeric, "Continuous", Format( "Best", 12 ),
Set Values( [1, 2, 3] ) ),
New Column( "Std Dev", Numeric, "Continuous", Format( "Best", 12 ),
Set Values( [0.5, 0.6, 0.7] ) )
);
my_newdt = New Table( "Target", Add Rows( 100 ) );
// For loop. Add Columns
For( i = 2, i <= N Rows( mydt ), i++, //
Eval( Eval Expr(
my_newdt << New Column( Column( mydt, 1 )[i],
Numeric,
"Continuous",
Format( "Best", 6 ),
Formula( Random Normal( Expr( As Column( mydt, :Mean )[i] ), Expr( As Column( mydt, :Std Dev )[i] ) ) )//
)
) )
);
Re: Insertar una expresión dentro de otra usando Eval Insert, Eval Expr, Parse y SubstituteCreando una tabla con fórmula en las columnas - Random Normal() - desde jmp externo
Ya tengo una solución funcional para mi problema. Enlace arriba.
Sin embargo, soy obsesivo en que mi código funcione correctamente.
Y este hilo parece responder a mi tema.
Probé algunas de las técnicas anteriores. Pero no funciona o no lo entiendo.
¿Tienes alguna sugerencia para mí? Cómo conseguir expresión " Como columna (mydt,: media) [1] " ¿resuelto a los valores de origen?
//not working
Clear Globals();
Names Default To Here( 1 ); //
mydt = Current Data Table();
// New data table
my_newdt = New Table( "Table Name",
// Add Rows( N Rows( mydt ) ), // row count can be set by hand e.g. 1000
Add Rows( 10 ), // row count can be set by hand e.g. 1000
New Column( Column( mydt, 1 )[1], // Loop i==1
Numeric,
"Continuous",
Format( "Best", 6 ),
Formula( Random Normal( As Column( mydt, :Mean )[1], 0.01))// As Column(mydt, :Mean )[1] is evalueted in the target table. But Formula has the expression "As Column( mydt, :Mean )[1]" instead of a value from source table
)
);// End New data table
/*// For loop. Add Columns
For( i = 2, i <= N Rows( mydt ), i++, //
my_newdt << New Column( Column( mydt, 1 )[i], // Loop i ==2
Numeric,
"Continuous",
Format( "Best", 6 ),
Set Each Value( Random Normal( As Column( mydt, :Mean )[i], As Column( mydt, :Std Dev )[i] ) )//
)
)// End for loop;
;*/
Re: Insertar una expresión dentro de otra usando Eval Insert, Eval Expr, Parse y Substitute¡Muy útil!
Re: Insertar una expresión dentro de otra usando Eval Insert, Eval Expr, Parse y SubstituteExcelente revisión de los métodos disponibles para construir dinámicamente expresiones JSL.Domina esto y todo será bastante sencillo.