Ho un dataframe modello che contiene 209 colonne etichettate 1-209. Spesso un client mi inoltrerà set di dati che hanno colonne combinate, ad esempio, la colonna 2 può essere aggiunta con la colonna 3 (etichettata "2 + 3") nel nuovo set di dati.
Come posso estrarre le colonne nel nuovo set di dati e usarle come formule per rendere le colonne uguali nel dataframe del modello? So che JMP ha una funzione di combinazione, ma come posso scrivere uno script che estrae tutti i nomi di colonna e li converte in formule per allineare i due set di dati.
Ho allegato l'aspetto del modello e dei set di dati di destinazione all'interno di questa email.
Ecco un semplice script che si espande sulle colonne combinate.Nota: hai un errore nei nomi delle colonne nella tabella dei dati del modello.Il nome della colonna 95 viene visualizzato due volte.Il secondo dovrebbe essere 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 )));
Ciao @MikeDereviankin ,
Non sono sicuro di aver capito completamente cosa cercavi, ma penso di sì e ci ho lavorato per circa un giorno. (Non sono un programmatore veloce o un esperto di JSL come @txnelson , sa la sua roba!). Inoltre non ho provato il suo codice, ma ci sono arrivato pensando in modo diverso (credo).
Il codice seguente prenderà i nomi delle colonne dalla tabella dati "target" che contengono "+", crea una nuova colonna formula nella tabella dati "modello" che aggiunge insieme quelle colonne specifiche. Quindi le sposta nella posizione corretta nella tabella dati ed elimina le colonne originali che sono state aggiunte insieme. Rimuove anche la proprietà della formula dalla colonna.
Ci è voluto circa un giorno per cercare il modo giusto per chiamare i nomi delle colonne perché sono numeri. È molto più facile avere nomi di caratteri per fare riferimento a loro senza i comandi Eval () e Parse (), ecc. Sono sicuro che qualcuno meglio può renderlo più elegante, ma funziona (almeno nel modo in cui ti ho interpretato chiedendo per come farlo). Ho inserito un comando Wait () lì dentro, ma probabilmente non ne hai bisogno.
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 ) || "\!")" ) ) );
);Spero che sia di aiuto!,
DS