<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />Utilizo 2 métodos para crear columnas de fórmula dependiendo de si sé cuántas variables necesita la fórmula
- Expr y substituto son fáciles de leer. La sección 1 del código crea varias columnas de fórmula para cada variable en una lista para la media ( var, byvar )
- Parse and eval y posiblemente eval insert crean una sola columna de fórmula que requiere un número de variables, el número y el nombre se establecen en la lista de variables.
- Las secciones 2a y 2b funcionan y son funcionalmente equivalentes
- Las secciones 2c y 2d no se ejecutan, pero parecen un camino hacia una solución elegante
Me gustaria ideas para crear mejores practicas y agradeceria recomendaciones
Nombres predeterminados hasta aquí ( 1 );
n=ntable();
dtnms={};
Si(
n==0, dtc=1,
n==1, If(tabla de datos actual() << get name == "Big Class", dtc=0, dtc=1), // else
for(ii=1, ii <= n, ii++, insert into(dtnms, data table(ii) << getname));
if(contains(dtnms, "Big Class") > 0, dtc=1, dtc=0);
);
if (dtc,dt = Open( "$SAMPLE_DATA/Big Class.jmp" ), dt = tabla de datos("Big Class"));
// Sección 1: Agregue varias columnas de fórmula ingresando variables dinámicamente.
Formulario1=expr(
form1col=dt << nueva columna(Nombre, fórmula(col mean(As Column(YVar), As Column(ByVar))))
);
VarList={"sexo", "altura", "peso"};
For(ii=2, ii <= N Elementos(VarList), ii++,
Eval(Sustituir(Nombre expr(formulario1),
expr(Nombre), VarList[ii]||" Promedios",
expr(YVar), VarList[ii],
expr(PorVar), ListaVar[1],
));
);
// Sección 2: Promediar las columnas en la lista de variables
// Método 2a El método funciona pero es difícil de depurar
VarList={"altura", "peso", "edad"};
Formtxt1 = "formcol = dt << nueva columna(\!"Método a: Media\!", fórmula(media( ";
Formtxt2 = "Como columna(\!""||VarList[1]||"\!")";
Si(
N elementos (VarList) == 2, Formtxt2 ||= ", como columna (\!""||VarList[2]||"\!")",
N Elementos (VarList)>2, For(ii=2, ii <= N Elementos (VarList), ii++,
Formtxt2 ||= ", Como columna(\!""||VarList[ii]||"\!")"
)
);
Formtxt=Formtxt1||Formtxt2||");";
eval(analizar(Formtxt));
// Método 2b: algo más fácil de ver
col4=expr(
NewCol1=dt << New Column("Método b: Media de "||_names_);
);
form4txt="NewCol1 <
VarList={"altura", "peso", "edad"};
VarRef = eval list(dt << obtener referencia de columna(VarList));
_Vars_ = "Como columna( \!"" || Elementos ConCat(VarList, "\!"), Como columna( \!"") || "\!")";
form4txta = Insertar evaluación (form4txt);
Eval(Sustituir(Nombre expr(col4),
expr(_names_), elementos concatenados(VarList,", ",)
));
Eval(Analizar(form4txta)); // Parse convierte el texto en una expresión que se evalúa
// *************************************** //
// ************* No funciona ************* //
//Método 2c: creo que este sería el mejor, pero no puedo corregirlo. Todavía tengo una lista
form3=expr(
NewCol=dt << New Column("Media de "||_names_, formula(Media(_Vars_ )));
);
VarList={"altura", "peso", "edad"};
VarRef = eval list(dt << obtener referencia de columna(VarList));
Eval(Sustituir(Nombre expr(formulario3),
expr(_names_), elementos concatenados(VarList,", ",),
expr(_Vars_), VarRef
));
// Método 2d: usando un bucle, pero sigue siendo incorrecto
form4=expr(
NewCol=dt << New Column("Media de "||_names_, formula(Media(_Vars_ )));
);
VarList={"altura", "peso", "edad"};
VarRef = eval list(dt << obtener referencia de columna(VarList));
Form4a =Sustituir(Nombre expr(form4),
expr(_names_), elementos concatenados(VarList,", ",)
);
For(ii=1, ii <= N Elementos(VarList), ii++,
form4a=Sustituir(Nombre expr(form4a),
expr(_Vars_), expr(VarRef[ii], _Vars_)
);
);
Eval(Sustituir(Nombre expr(form4a),
expr(_Vars_), ""
));
// *************************************** //
// ************* No funciona ************* //
Buena colección de diferentes métodos.
Últimamente he llegado a preferir trabajar con expresiones en lugar de cadenas en casos como este. Para establecer una fórmula por JSL, primero construyo la expresión usando EvalExpr(), que luego inserto con NameExpr() para evitar la evaluación en tiempo de ejecución.
A continuación, se muestran dos ejemplos basados en una lista de nombres de columna o una lista de cadenas, la última es un poco más desafiante.
dt = Abierto ( "$SAMPLE_DATA/Clase grande.jmp" ) ;
// 1. Lista de nombres de columnas
L1 = { edad , altura , peso } ; // es decir, dt<
formulario 1 = Expr evaluación ( Significar ( exp. ( L1 ))) ;
formulario1col = dt << Nueva columna ( Artículos combinados ( Palabras ( Carbonizarse ( L1 ) , "{}," )) || " Promedio" , fórmula ( Nombre Expr. ( formulario 1 ))) ;
// 2. Lista de cadenas
L2 = { "edad" , "altura" , "peso" } ; // es decir, dt<
formulario2 = Expr evaluación (
Significar (
exp. (
Repetir (
i = 0 ;
{ i ++ ; Expr evaluación ( como columna ( exp. ( L2 [ i ])))} ;,
N elementos ( L2 )
)
)
)
) ;
formulario2col = dt << Nueva columna ( Artículos combinados ( L2 ) || " Promedio" , fórmula ( Nombre Expr. ( formulario2 ))) ;