Sto tentando di estrarre i valori delle colonne per le righe selezionate in un'etichetta concatenata che viene utilizzata per annotare una riga di riferimento aggiunta in una distribuzione.
Il messaggio di errore nella concatenazione è dovuto a una mancata corrispondenza nelle dimensioni dell'elenco. Le chiamate Associative Array utilizzate per raccogliere i valori dalle righe selezionate stanno rimuovendo i valori duplicati, con conseguenti elenchi di valori univoci.
Il mio obiettivo è quello di ottenere il nome, l'età e il peso di una determinata riga selezionata in una stringa che può essere utilizzata come etichetta in una successiva chiamata add ref.
Con l'approccio attuale ho codici di errore e in alcuni casi un disallineamento nei dati senza codice di errore.
Esempio 1 - Condizione di errore: sono stati trovati tre pesi univoci in cui gli elenchi per età e nomi hanno trovato solo due elementi ciascuno dalle righe selezionate. La terza iterazione dell'indicizzazione fallisce a causa delle differenze nelle dimensioni dell'elenco.
Esempio 2 - Dati non allineati: ci sono tre righe selezionate usando i nomi Leslie e Patty. Ci sono due voci con il nome Patty, una età 14 e peso 85, l'altra età 16 e peso 134. Una delle voci per Patty e la voce per Leslie hanno entrambe 14 anni. Il risultato dei dati non allineati può essere visto se l'etichetta considera solo gli elenchi per nome {"LESLIE", "PATTY"} ed età {14,16}. L'indicizzazione creerebbe solo due voci, la prima è "Leslie ...14" la seconda è "Patty ...16" che è un'associazione corretta ma "Patty ...14" è mancante e le dimensioni dell'elenco sono dipendenti dai dati.
Dovrei rimuovere le chiamate di array associativi e passare invece a un approccio di sottoinsieme/tabella oppure dovrei rivedere le chiamate di array associativi per avere elementi di elenco che siano elenchi con nome, età e peso acquisiti in ogni iterazione o per ogni riga selezionata?
Grazie,
Bryan
Codice di errore quando vengono superate le dimensioni degli elenchi:
l'argomento dovrebbe essere un carattere alla riga 41 nell'accesso o nella valutazione di 'Concat', argomento non valido (theAges[i]), theNames[i] || /*###*/" ..." || /*###*/theAges[i] /*###*/

Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
col_name_list = dt << get column names( string );
newColName = "State";
// New column: State
If( !Contains( col_name_list, newColName ),
Local( {dt, tempStrings},
dt = Data Table( "Big Class" );
dt << New Column( "State", Character, "Nominal" ) << Begin Data Update;
tempStrings = {"CA", "WA", "OR"};
For Each Row( dt, :State = tempStrings[Sequence( 1, 3, 1, 1 )] );
dt << End Data Update;
);
//Make it a double Patty :), another person with the same name.
dt << Add Rows( 1, At End );
//Cheat and use a constant of 41 for the last row index
dt[[41], {name, age, sex, height, weight, State}] = {{"PATTY", 16, "F", 57, 134, "WA"}};
);
// For illustration, select some names
dt << select where( Contains Item( :name, {"LESLIE", "PATTY"} ) );
dist = dt << Distribution(
Stack( 1 ),
Continuous Distribution(
Column( :height ),
Quantiles( 0 ),
Summary Statistics( 0 ),
Horizontal Layout( 1 ),
Normal Quantile Plot( 0 ), // disable, if the user enabled it in the preferences :)
Vertical( 0 ),
Set Bin Width( 2 ),
Process Capability( 0 )
//);
),
By( :State )
);
// get all reports
// if there is a BY group, get the info - if there is none, put it into a list
If( Is List( dist ),
dists=dist;
myBys = Transform each ({myexpr} , dist << Get Where Expr, Arg(myExpr , 2 ))
, //no By
dists = Eval List( {dist} );
myBys= {};
);
//get the reports
distRPTs = Transform Each( {dist}, dists, Report( dist ) );
// Find the Midpoints of the bins the selected rows are in
dist << Save( "Level Midpoints" );
//loop though the By groups and add the reflines
For Each( {report, idx}, distRPTs,
//report = distRPTs[2]; idx=2;
selected rows = dt << get selected rows;
// there is a BY group -> restrict the selection
if(N Items(myBys),
Eval( Eval Expr( selected rows = dt << get rows where( Contains( Expr( selected rows ), Row() ) & :State == Expr( myBys[idx] ) ) ) );
);
theBins = (Associative Array( Column( dt, N Cols( dt ) )[selected rows] )) << get keys;
theNames = (Associative Array( Column(dt, "name") [dt << get selected rows] )) << get keys;
theAges = (Associative Array( Column(dt, "age") [dt << get selected rows] )) << get keys;
theWeights = (Associative Array( Column(dt, "weight") [dt << get selected rows] )) << get keys;
For( i = 1, i <= N Items(theWeights), i++,
theLabels[i] = theNames[i] || " ..." || theAges[i] ;
);
);
dt << delete columns( N Cols( dt ) );Ciao Bryan, potresti usare una colonna di trasformazione per preparare i risultati corretti e poi selezionare le voci di cui hai bisogno:

Vedi altro...Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
col_name_list = dt << get column names( string );
newColName = "State";
// New column: State
If( !Contains( col_name_list, newColName ),
Local( {dt, tempStrings},
dt = Data Table( "Big Class" );
dt << New Column( "State", Character, "Nominal" ) << Begin Data Update;
tempStrings = {"CA", "WA", "OR"};
For Each Row( dt, :State = tempStrings[Sequence( 1, 3, 1, 1 )] );
dt << End Data Update;
);
//Make it a double Patty :), another person with the same name.
dt << Add Rows( 1, At End );
//Cheat and use a constant of 41 for the last row index
dt[[41], {name, age, sex, height, weight, State}] = {{"PATTY", 16, "F", 57, 134, "WA"}};
);
// For illustration, select some names
dt << select where( Contains Item( :name, {"LESLIE", "PATTY"} ) );
dist = dt << Distribution(
Stack( 1 ),
Continuous Distribution(
Column( :height ),
Quantiles( 0 ),
Summary Statistics( 0 ),
Horizontal Layout( 1 ),
Normal Quantile Plot( 0 ), // disable, if the user enabled it in the preferences :)
Vertical( 0 ),
Set Bin Width( 2 ),
Process Capability( 0 )
//);
),
By( :State )
);
// get all reports
// if there is a BY group, get the info - if there is none, put it into a list
If( Is List( dist ),
dists=dist;
myBys = Transform each ({myexpr} , dist << Get Where Expr, Arg(myExpr , 2 ))
, //no By
dists = Eval List( {dist} );
myBys= {};
);
//get the reports
distRPTs = Transform Each( {dist}, dists, Report( dist ) );
// Find the Midpoints of the bins the selected rows are in
dist << Save( "Level Midpoints" );
dt << transform column ("label",Character, Formula (:name || " ..." || Char(age)));
//loop though the By groups and add the reflines
For Each( {report, idx}, distRPTs,
//report = distRPTs[2]; idx=2;
selected rows = dt << get selected rows;
// there is a BY group -> restrict the selection
if(N Items(myBys),
Eval( Eval Expr( selected rows = dt << get rows where( Contains( Expr( selected rows ), Row() ) & :State == Expr( myBys[idx] ) ) ) );
);
myLabels = Associative Array(:label[selected rows]) << get keys;
print(myLabels)
);
dt << delete columns( N Cols( dt ) );
Ciao @hogi
Ho unito le tue idee in questo post e nel post correlato sull'aggiunta di una riga di riferimento.
La soluzione che funziona per allineare le informazioni corrette senza perdita di valori ripetuti, aggiungendo correttamente i contenitori ai grafici nello stack, consisteva nel preparare elenchi dai campi nella tabella indicizzando le righe selezionate all'interno di un ciclo for nidificato.
- Distribuzioni di trama
- Raccogli in base ai criteri in un array per ciascuno dei grafici in un'istanza nel report (3 grafici per ogni elemento di dati, 3 array)
- Raccogliere i report in un oggetto utilizzato nell'iterazione
- Aggiungere i punti medi per i dati tracciati (3 grafici, 3 colonne aggiunte alla tabella dati)
- Eseguire un ciclo attraverso l'oggetto con un For Each per accedere e aumentare ogni grafico
- Inizializza le variabili di elenco per contenitori ed etichette
- Seleziona le righe nei dati in base ai criteri di base (ad esempio numero di serie)
- Affina le righe selezionate in base ai criteri corrispondenti ai criteri Per nei grafici
- Utilizzare un ciclo for per tutte le righe selezionate
- Raccogliere i contenitori dalle colonne dei punti medi aggiunte (ogni grafico ha una rispettiva colonna)
- Raccogliere le informazioni nell'etichetta dalle colonne interessanti (ad esempio Data di misurazione, Numero di serie)
- Aggiungere una riga di riferimento con le informazioni raccolte.
- Eliminare le colonne del punto medio per evitare dati obsoleti nel caso in cui vengano modificate le impostazioni del grafico nel passaggio 1.
Cambiamenti chiave che hanno aiutato:
1. Passare da un array associativo a elenchi popolati tramite iterazione per evitare l'eliminazione di valori duplicati, mantenendo l'allineamento.
2. Creare variabili separate per ciascuna delle condizioni.
Spero che questo aiuti a chiudere il cerchio. I tuoi consigli sono apprezzati. Hanno permesso il mio apprendimento e il mio progresso.