<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />Con frecuencia me preguntan cómo escribir una fórmula (aplicar la misma fórmula a varias columnas, usando algo sobre la columna de referencia en la fórmula). Este suele ser un lugar de entrada para que las personas también comiencen a escribir scripts, por lo que son novatos.
Recientemente publiqué una pregunta en la sección de discusión habitual, intentando que mi cliente participara (no lo hicieron) y algunos consejos de expertos (cualquiera que lea esto). Realmente me gustaría generar una respuesta sólida a la que pueda indicarle a la gente cuando surja esta pregunta. Por ejemplo, ¿la respuesta sugerida es realmente la mejor manera de hacerlo si tiene más de 1000 columnas, etc.?
Cualquier ayuda en esto sería apreciada. O una entrada de blog. ¿O señalar que esto se ha tratado en otro lugar?
La discusión habitual está aquí:
¿La mejor manera de escribir una fórmula de columna en muchas columnas?
¡Gracias!
Como continuación de lo anterior: notarás que uso la función :Name() para los nombres de las columnas. Esto ayuda a evitar cualquier problema que surja por tener caracteres interesantes en los nombres de las columnas. No siempre es necesario, pero repito, a prueba de balas.
Siguiendo lo que dijo Don, a menudo me encuentro yendo un paso más allá, usando Eval(Parse(Substitute())).
De hecho, esto es escribir el código dinámicamente. Aunque algo poco elegante, es casi a prueba de balas. Esta construcción no siempre es la más eficiente (debido a las sustituciones de personajes), pero es la que tiene éxito cuando todos los demás trucos fallan, por lo que es bueno conocerla. El inconveniente más importante es que no se puede ver el código de colores debido a las citas:
Nombres predeterminados aquí ( 1 ) ;
dt = abierto ( "$Sample_Data/futbol.jmp" ) ;
códigoFrag = "\[
Nueva columna( "_colName_ Rango desde la media",
Numérico,
"Continuo",
Formato( "Mejor", 12 ),
Fórmula( Rango de columna( Abs( Media de columna( :Nombre( "_colName_")) - :Nombre( "_colName_" ) ) ) )
)
]\" ;
listacol = dt << obtener nombres de columnas ( cadena ) ;
para ( i = 1 , i <= nitems ( colista ) , i ++,
si ( columna ( dt , listacol [ i ]) << obtener tipo de modelado == "Continuo" ,
evaluar ( analizar gramaticalmente ( sustituto ( códigoFrag , "_colName_" , listacol [ i ])))
)
) ;
Si le molesta la falta de codificación de colores, puede mantenerla envolviendo la cadena en una construcción char(nameexpr()), como se muestra a continuación. Esto agrega complejidad, pero puede valer la pena escribir el código con fines de depuración... una vez que funcione, siempre puedes quitar la pieza char(nameexpr()) y colocarla entre comillas usando "\[ ]\".
En pocas palabras: esto no ganará un concurso de belleza, pero cuando escribas la cadena tú mismo, la analices y la evalúes, obtendrás lo que buscas. Guárdelo en su bolsillo trasero para cuando Eval(EvalExpr( ...... Expr() .... )) falla y no eres capaz de descubrir (o no tienes tiempo para descubrirlo, o no te importa) por qué.
Nombres predeterminados aquí ( 1 ) ;
dt = abierto ( "$Sample_Data/futbol.jmp" ) ;
códigoFrag = carbonizarse ( nombreexpr (
Nueva columna ( "_colName_ Clasificación desde la media" ,
Numérico ,
"Continuo" ,
Formato ( "Mejor" , 12 ) ,
Fórmula ( Rango de columna ( Abdominales ( Col media ( : Nombre ( "_colName_" )) - : Nombre ( "_colName_" ) ) ) )
)
)) ;
listacol = dt << obtener nombres de columnas ( cadena ) ;
para ( i = 1 , i <= nitems ( colista ) , i ++,
si ( columna ( dt , listacol [ i ]) << obtener tipo de modelado == "Continuo" ,
evaluar ( analizar gramaticalmente ( sustituto ( códigoFrag , "_colName_" , listacol [ i ])))
)
) ;
Salud,
Brady
laura,
Creo que la respuesta dada en el Foro es un enfoque sólido que no complica el código más de lo necesario. Creo que el uso de Expr y Name Expr es inevitable en esta situación. Como siguiente paso, podría considerar eliminar la fórmula del bucle para que el código sea más genérico. De esta manera, puede crear una función que tome fórmulas como argumento (consulte el JSL adjunto). Probablemente haya una forma más sencilla de hacer esto, pero estoy muy acostumbrado a usar Substitute (y es extremadamente sólido). No estoy seguro de por qué se necesita la parte [Fila()], pero es para cualquier momento en el que haga referencia a una columna, excepto dentro de una función de columna estadística. Espero que esto proporcione alguna idea.
Don