Tengo un marco de datos de plantilla que contiene 209 columnas etiquetadas 1-209. A menudo, un cliente me reenviará conjuntos de datos que tienen columnas combinadas, por ejemplo, la columna 2 se puede agregar con la columna 3 (etiquetada como '2 + 3') en el nuevo conjunto de datos.
¿Cómo puedo extraer las columnas en el nuevo conjunto de datos y usarlas como fórmulas para hacer que las columnas sean iguales en el marco de datos de la plantilla? Sé que JMP tiene una función de combinación, pero ¿cómo puedo escribir un script que extraiga todos los nombres de las columnas y los convierta en fórmulas para alinear los dos conjuntos de datos?
Adjunto cómo se ven la plantilla y los conjuntos de datos de destino en este correo electrónico.
Aquí hay una secuencia de comandos simple que se expande en las columnas combinadas.Nota: tiene un error en los nombres de las columnas en la tabla de datos de la plantilla.El nombre de la columna 95 aparece dos veces.Se supone que el segundo es 98.
Names Default To Here( 1 );
// Point to the 2 data tables....assumption is they are open
dtTemplate = Data Table( "Template_Template" );
dtTarget = Data Table( "Target_Target" );
// Create a template data table with just the column names
dtHeader = dtTemplate << subset( selectd rows( 0 ), selected columns( 0 ) );
dtHeader << select where( Row() > 0 );
dtHeader << delete rows;
// Change the column data type to match in incoming target data
dtHeader:Column 1 << datatype( character );
// Concatenate the data together. JMP will match all columns with the
// same name, and create new columns for ones that don't have a match
dtInterim = dtHeader << concatenate( dtTarget );
// Loop across the new columns and assign the values back to the columns
// the values need to be in
For( i = N Cols( dtHeader ) + 1, i <= N Cols( dtInterim ), i++,
start = Num( Word( 1, Column( dtInterim, i ) << get name, "+" ) );
end = Num( Word( 2, Column( dtInterim, i ) << get name, "+" ) );
For( k = start, k <= end, k++,
Column( dtInterim, Char( k ) )[1] = Column( dtInterim, i )[1]
);
);
// Delete the extra columns
dtInterim << delete columns( index(N Cols( dtHeader ) + 1, N Cols( dtInterim )));
Hola @MikeDereviankin ,
No estoy seguro de haber entendido completamente lo que buscabas, pero creo que sí, y trabajé en ello durante aproximadamente un día. (No soy un programador tan rápido o un experto en JSL como @txnelson , él sabe lo que hace!). Tampoco probé su código, pero lo pensé de manera diferente (creo).
El siguiente código tomará los nombres de las columnas de la tabla de datos "objetivo" que tienen "+" en ellos, creará una nueva columna de fórmula en la tabla de datos de "plantilla" que suma esas columnas específicas. Luego, los mueve a la ubicación adecuada en la tabla de datos y elimina las columnas originales que se agregaron. También elimina la propiedad de la fórmula de la columna.
Me tomó alrededor de un día buscar la forma correcta de llamar a los nombres de las columnas porque son números. Es mucho más fácil tener nombres de caracteres para hacer referencia a ellos sin los comandos Eval () y Parse (), etc. Estoy seguro de que alguien mejor puede hacerlo más elegante, pero esto funciona (al menos de la forma en que lo interpreté preguntando para saber cómo hacerlo). Puse un comando Wait () allí, pero probablemente no lo necesite.
Names Default To Here( 1 );
//defines the two data tables, they must be open already and named appropriately
dt_target = Data Table( "Target" );
dt_template = Data Table( "Template" );
//This gets the column names for each table
target_col_names = dt_target << get columnnames( Numeric, string );
template_col_names = dt_template << get column Names( Numeric, string );
//This tests the column names in the target data table to see if there is a "+" and if so puts that column name in the target_col_keep list
target_col_keep = {};
For( i = 1, i <= N Cols( dt_target ) - 1, i++,
If( Contains( target_col_names[i], "+" ) != 0,
Insert Into( target_col_keep, target_col_names[i] )
)
);
//This loops through the items in target_col_keep to make new columns and add formulas.
//The complicated part of As Column(Num(Word(Eval(EvalExpr(Expr()))))) basically converts the number names to a reference-able column.
//The extra +1 is there because of the first column in the dt_template data table -- it offsets the column numbers on down the line in <BR />//reference to the target data table.
//The first word command gets only the first column of the added up to the "+", hence Word(1,...)
//The second word command gets only the second word after the "+", hence Word(2,...)
//The new columns are added to the end of the data table.
i=.;//reset counter
For( i = 1, i <= N Items( target_col_keep ), i++,
dt_template << New Column( target_col_keep[i],
"Numeric",
"continuous",
Formula(
As Column( (Num( Word( 1, Eval( Eval Expr( Expr( target_col_keep[i] ) ) ), "+" ) ) + 1) ) + As Column(
(Num( Word( 2, Eval( Eval Expr( Expr( target_col_keep[i] ) ) ), "+" ) ) + 1)
)
)
);
//this step moves the newly created column after the second column of the sum. Comment out if you don't want to move them.
prevcol = Num( Word( 1, Eval( Eval Expr( Expr( target_col_keep[i] ) ) ), "+" ) );
dt_template << select Columns( As Column( Eval( Eval Expr( Expr( target_col_keep[i] ) ) ) ) ) <<
Move Selected Columns( After( Column( Parse( ":Name(\!"" || Char( prevcol ) || "\!")" ) ) ) );
);
Wait(0.5);
//This part removes the formula. Comment out if you don't want to remove the formula.
j = .;//reset counter
For( j = 1, j <= N Col( dt_template ), j++,
As Column( j ) << Delete property( "Formula" )
);
//This deletes the old columns that were added together. Comment out if you don't want to delete them.
k=.;//reset counter
For( k = 1, k <= N Items( target_col_keep ), k++,
str1 = Num( Word( 1, Eval( Eval Expr( Expr( target_col_keep[k] ) ) ), "+" ) );
str2 = Num( Word( 2, Eval( Eval Expr( Expr( target_col_keep[k] ) ) ), "+" ) );
dt_template << Delete Columns( Column( Parse( ":Name(\!"" || Char( str1 ) || "\!")" ) ) );
dt_template << Delete Columns( Column( Parse( ":Name(\!"" || Char( str2 ) || "\!")" ) ) );
);¡Espero que esto ayude!,
DS