Modo migliore per selezionare le colonne che corrispondono ai criteri in un'altra colonna nella stessa tabella?Lo script alla fine di questo post fa fondamentalmente quello che voglio che faccia (cioè trovare colonne in cui un valore Y è 100 per time = 0), ma genera anche un messaggio di log che mi mette un po' a disagio (avendo fatto un passo in trappole prima):
A message with an empty Boolean argument enabled an option that was already enabled. That option remains enabled. In previous versions of JMP, this would have disabled the option.
Questo messaggio viene stampato nel registro per ogni colonna selezionata di nuovo, dopo che è già stata selezionata una volta come parte della costruzione del ciclo. Essendo una persona relativamente nuova allo scripting, ho due preoccupazioni principali:
- Questo messaggio di registro è qualcosa che dovrei assolutamente evitare e mi imbatterò in problemi? Alla fine elaborerò tabelle più grandi, quindi questo messaggio di registro potrebbe essere stampato centinaia di volte per l'esecuzione di un singolo script.
- C'è un modo più intelligente per trovare tutte le colonne in una tabella che hanno un valore Y = 100 per ogni riga dove tempo = 0? (Nel mio caso, elaborerò tabelle con molte colonne, alcune delle quali contengono risultati normalizzati al 100% rel. al tempo =0. Queste sono le colonne che mi interessano.)
Names Default To Here( 1 );
// table required for example
dt = New Table( "Results (absolute & relative) vs time",
Add Rows( 8 ),
New Column( "time",
Numeric,
Set Values( [0, 1, 2, 3, 0, 1, 2, 3] ),
),
New Column( "Y1_absolute",
Numeric,
Set Values( [7, 8, 1, 9, 0.2, 0.4, 0.65, 0.98] ),
),
New Column( "Y1-relative",
Numeric,
Set Values( [100, 114, 14, 129, 100, 200, 325, 490] ),
),
New Column( "Y2_absolute",
Numeric,
Set Values( [12, 6, 4, 0, 80, 90, 120, 75] ),
),
New Column( "Y2_relative",
Numeric,
Set Values( [100, 50, 33, 0, 100, 113, 150, 94] ),
)
);
// selecting columns where for :time == 0 a Y-value == 100 is found
For( i = 1, i <= N Row( dt ), i++,
For( j = 1, j <= N Col( dt ), j++,
If( Column( j )[i] == 0,
For( k = 1, k <= N Col( dt ), k++,
If( Column( k )[i] == 100,
Column( k ) << Set Selected
)
)
)
)
);
Tabella datiScriptingRi: Modo migliore per selezionare le colonne che corrispondono ai criteri in un'altra colonna nella stessa tabella?FWIW, questo evita la tabella dei sottoinsiemi, ma probabilmente non è molto più veloce:
Names Default To Here( 1 );
// table required for example
dt = New Table( "Results (absolute & relative) vs time",
Add Rows( 8 ),
New Column( "time",
Numeric,
Set Values( [0, 1, 2, 3, 0, 1, 2, 3] ),
),
New Column( "Y1_absolute",
Numeric,
Set Values( [7, 8, 1, 9, 0.2, 0.4, 0.65, 0.98] ),
),
New Column( "Y1-relative",
Numeric,
Set Values( [100, 114, 14, 129, 100, 200, 325, 490] ),
),
New Column( "Y2_absolute",
Numeric,
Set Values( [12, 6, 4, 0, 80, 90, 120, 75] ),
),
New Column( "Y2_relative",
Numeric,
Set Values( [100, 50, 33, 0, 100, 113, 150, 94] ),
)
);
// Rows that have time = 0
r0 = dt << getRowsWhere(:time == 0);
// Loop over other columns (assumes time is in the first column)
for(c=2, c<=NCol(dt), c++,
if(Contains(Column(dt, c)[r0], 100), Column(dt, c) << setSelected(1));
);
Ri: Modo migliore per selezionare le colonne che corrispondono ai criteri in un'altra colonna nella stessa tabella?Grazie ancora. La sottoimpostazione ha migliorato le prestazioni sul mio tavolo reale (grande). Soluzione migliorata pubblicata di seguito. Ci avevo pensato prima, ma ovviamente avevo bisogno di una breve pausa per arrivarci. Quello che non avevo nemmeno considerato era la creazione di un elenco di colonne e la rimozione iterativa degli elementi. Grazie anche per questo!
Names Default To Here( 1 );
// new table required for example
dt = New Table( "Results (absolute & relative) vs time",
Add Rows( 8 ),
New Column( "time",
Numeric,
Set Values( [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3] ),
),
New Column( "Y1_absolute",
Numeric,
Set Values( [7, 8, 1, 9, 0.2, 0.4, 0.65, 0.98, 0.7, ., 0.83, 0.4] ),
),
New Column( "Y1-relative",
Numeric,
Set Values( [100, 114, 14, 129, ., 200, 325, 490, 100, 330, 540, 213] ),
),
New Column( "Y2_absolute",
Numeric,
Set Values( [12, 6, 4, 0, 80, 90, 120, 75, 8.3, 9.7, 6.4, 5.2] ),
),
New Column( "Y2_relative",
Numeric,
Set Values( [., 50, 33, 0, 100, 113, 150, 94, 100, 66, 37, 12] ),
)
);
// finding and selecting Y columns where for any :time == 0 a value of 100 is found in the same row
dt << Select Where( dt:time == 0 );
dtTemp = dt << Subset ( Selected Rows, Selected Columns Only( 0 ) );
For( i = 1, i <= N Row( dtTemp ), i++,
For( j = 1, j <= N Col( dtTemp ), j++,
If( Column( dtTemp, j )[i] == 100,
Column( dt, j ) << Set Selected( 1 ),
)
)
);
Close( dtTemp, no save );
dt << Clear Select( );
Ri: Modo migliore per selezionare le colonne che corrispondono ai criteri in un'altra colonna nella stessa tabella?Qualche idea:
Potresti provare a sottoimpostare la tabella su time=0 prima di procedere con il tuo ciclo. Ciò decomprimerebbe uno strato del tuo ciclo for.
Potresti creare un elenco di colonne e rimuovere quelle che hai selezionato. Quindi per ogni iterazione successiva dovresti solo scorrere le rimanenti colonne non selezionate.
Ri: Modo migliore per selezionare le colonne che corrispondono ai criteri in un'altra colonna nella stessa tabella?Molto apprezzato! Penso che modificherò quel ciclo un po 'di più.
- Non c'è motivo di attraversare l'intera tabella una volta identificate le colonne corrette. (Modifica: potrebbe essere un po' difficile da fare con il mio attuale livello di abilità. Diverse colonne Y possono avere valori mancanti in diverse righe. Devo trovare tutte le colonne Y in cui time = 0 corrisponde a uno o più valori Y = 100.)
- Perché scorrere tutte le righe e non solo quelle in cui il tempo è effettivamente zero?
Modifica: è rimasto con la soluzione presentata. Sembra robusto e non voleva usare ancora più tempo. Ma il punto n. 2, ovvero non scorrere tutte le righe della tabella è qualcosa che dovrei e probabilmente esaminerò a un certo punto.
Ri: Modo migliore per selezionare le colonne che corrispondono ai criteri in un'altra colonna nella stessa tabella?L'aggiunta di (1) dopo << set selected risolve il messaggio di errore. Invece di attivarlo, stai definendo lo stato finale che desideri:
For( i = 1, i <= N Row( dt ), i++,
For( j = 1, j <= N Col( dt ), j++,
If( Column( j )[i] == 0,
For( k = 1, k <= N Col( dt ), k++,
If( Column( k )[i] == 100,
Column( k ) << Set Selected(1)
)
)
)
)
);