[JSL] Script per il test T a due lati su un gran numero di metricheCiao a tutti,
Vorrei scrivere uno script JSL per automatizzare un TOST (Two-One Side T-Test) su un gran numero di metriche (oltre 500).
Il TOST funziona per coppie di "livelli", quindi lavorare con livelli 2x è facile, perché richiede solo 1 riga per "coppia".
Ho già scritto uno script che funziona bene per i livelli 2x generando una "tabella dati combinati" e aggiungendovi più colonne con formule, che finiscono con i risultati: "Equivalente" o "Non equivalente".
Il problema si complica quando voglio lavorare con più di 2x Livelli, perché sarebbe necessario trovare tutte le possibili coppie univoche di "Livelli" e quindi eseguire la matematica TOST per ogni combinazione di Metrica + coppie di Livelli.
Ho trovato un modo (su questo forum) per trovare tutte le possibili coppie univoche da un elenco e inserirle in una tabella o in un elenco nidificato (NchooseKmatrix()).
Ma sono bloccato lì. Ciò di cui ho bisogno è:
1- per popolare una nuova tabella con tutte le possibili combinazioni di Metriche (Colonna1) e tutte le coppie di possibili livelli (Colonna2 e Colonna3).
2- Quindi aggiungi le statistiche per ogni coppia di livelli su ogni riga
Da questo punto sarò in grado di calcolare la matematica necessaria per completare il TOST.
Ho allegato uno script che genera una tabella fittizia, quindi una tabella dati combinata dall'analisi unidirezionale, quindi il mio tentativo non riuscito di creare una terza tabella con tutte le combinazioni di metriche + coppie univoche di livello
Grazie in anticipo per il tuo aiuto
Names Default To Here( 1 );
clear symbols();
Deletesymbols();
//Create table with random distribution (table 1)
dt = New Table( "tabletest",
Add Rows( 500 ),
New Column( "Product", Character, "Nominal", formula("Product " ||char( Random Integer( 1, 4 )))),
New Column( "Metric1", Numeric, "Continuous", formula( Random Normal( 10, 1 ) ) ),
New Column( "Metric2", Numeric, "Continuous", formula( Random Gamma( 10, 1 ) ) ),
New Column( "Metric3", Numeric, "Continuous", formula( Random Gamma( 10, 2 ) ) )
);
Column( dt, "Metric1" ) << set property( "spec limits", {LSL( 5 ), USL( 25 ), Show Limits( 0 )} );
Column( dt, "Metric2" ) << set property( "spec limits", {LSL( 0 ), USL( 40 ), Show Limits( 0 )} );
Column( dt, "Metric3" ) << set property( "spec limits", {LSL( 5 ), USL( 40 ), Show Limits( 0 )} );
dt << save( "$Desktop\tabletest.jmp" );
//Get a list from all unique Product
SplitBy = "Product";
summarize(ColumnSplitBy=by(Column (SplitBy)));
show(ColumnSplitBy);
For( i = N Items( ColumnSplitBy ), i > 0, i--,
If( ColumnSplitBy[i] == "",
Remove From( ColumnSplitBy, i, 1 );
)
);
//Get Column name
MetricCols = dt << Get Column Names( numeric, continuous, "string" );
//Get all unique combo of 2 Products
ColumnSplitByCombo = aslist( nchoosekMatrix(nitems(ColumnSplitBy), 2));
show (ColumnSplitByCombo);
//Create a combinaed datatable with stats (Table 2)
ow = dt << Oneway(
Y(Eval(MetricCols)),
X(Eval(SplitBy)),
Means and Std Dev(1),
SendToReport(
Dispatch(
{"Means and Std Deviations"},
"Std Dev Lower 95%",
NumberColBox,
{Visibility("Visible")}
),
Dispatch(
{"Means and Std Deviations"},
"Std Dev Upper 95%",
NumberColBox,
{Visibility("Visible")}
)
),
Invisible
);
tb = Report(ow[1])[Outline Box("Means and Std Deviations"), Table Box(1)];
dt2 = tb << Make Combined Data Table;
tb << close window;
//Create new table for the result, each row has a unique pair of Levels
dt3 = astable( nchoosekMatrix(nitems(ColumnSplitBy), 2), << column names({"x", "y"}) );
dt3 << new column ("first", character, << set values ( ColumnSplitBy[dt3:x << get values]));
dt3 << new column ("second", character, << set values ( ColumnSplitBy[dt3:y << get values]));
dt3 << delete columns (1::2);
//Create a nested list with each pair of levels
Listdt3 = aslist( nchoosekMatrix(nitems(ColumnSplitBy), 2));
show (Listdt3);
// I tried to use associate array() to match the level and name but couldn't make it work- Predicatore
Automazione e scriptingRe: [JSL] Script per il test T a due lati su un gran numero di metricheHo allegato un documento "Untitled.png" con degli screenshot per (spero) spiegare meglio la mia richiesta.
Grazie!
Re: [JSL] Script per il test T a due lati su un gran numero di metricheAd esempio, potresti prima impilare la colonna del gruppo, aggiornarla con i risultati e dividerla di nuovo.
Questo esempio non tiene conto del fatto che possono esserci più metriche
// Loop over Metrics and perform these for each of them
// Concatenate results into single table
dt3 = As Table(NChooseK Matrix(N Items(ColumnSplitBy), 2), <<COLUMN names=""></COLUMN>// Metrics should be taken into account here OR stacked table should contain them
dt4 << Update(
With(dt2),
Match Columns(:Data = :Level)
);
o non ha la divisione finale che molto probabilmente assomiglia a qualcosa del genere

Re: [JSL] Script per il test T a due lati su un gran numero di metricheCiao @Voizingu : il TOST verifica solo se l'intervallo di confidenza del 100(1-2alfa)% è contenuto interamente entro alcuni limiti di equivalenza; quindi, forse una soluzione alternativa adeguata sarebbe quella di utilizzare la procedura di confronti multipli Fit Y by X per eseguire tutte le combinazioni per te?
Re: [JSL] Script per il test T a due lati su un gran numero di metricheC'è un motivo per cui non è possibile utilizzare il test di equivalenza integrato nella piattaforma Oneway?
Re: [JSL] Script per il test T a due lati su un gran numero di metricheCiao Jarmo,
Stack > Aggiorna > Dividi è un'idea fantastica!!!
Sono riuscito a implementarlo con successo, ma il mio codice è un po' sporco (molti cicli For(), passaggi intermedi,...).
Invece di:
- Concatenare la tabella più volte
- Quindi popolando una colonna da un elenco di metriche ripetute
Vorrei migliorare l'ottimizzazione del mio codice.
Esiste un modo per popolare dt5 in modo più pulito/ottimizzato? (magari utilizzando i comandi JMP nativi?)
Mi piacerebbe ricevere i tuoi suggerimenti su questo
Ma comunque, grazie mille per avermi aiutato in questo:D
- Predicatore
Names Default To Here( 1 );
clear symbols();
Deletesymbols();
//Create table with random distribution (table 1)
dt = New Table( "tabletest",
Add Rows( 5000 ),
New Column( "Product", Character, "Nominal", formula("Product " ||char( Random Integer( 1, 4 )))),
New Column( "Metric1", Numeric, "Continuous", formula( Random Normal( 10, 1 ) ) ),
New Column( "Metric2", Numeric, "Continuous", formula( Random Gamma( 10, 1 ) ) ),
New Column( "Metric3", Numeric, "Continuous", formula( Random Gamma( 10, 2 ) ) ),
);
Column( dt, "Metric1" ) << set property( "spec limits", {LSL( 5 ), USL( 25 ), Show Limits( 0 )} );
Column( dt, "Metric2" ) << set property( "spec limits", {LSL( 0 ), USL( 40 ), Show Limits( 0 )} );
Column( dt, "Metric3" ) << set property( "spec limits", {LSL( 5 ), USL( 40 ), Show Limits( 0 )} );
dt << save( "$Desktop\tabletest.jmp" );
//Get a list from all unique Product
SplitBy = "Product";
summarize(ColumnSplitBy=by(Column (SplitBy)));
show(ColumnSplitBy);
For( i = N Items( ColumnSplitBy ), i > 0, i--,
If( ColumnSplitBy[i] == "",
Remove From( ColumnSplitBy, i, 1 );
)
);
//Get Column name
MetricCols = dt << Get Column Names( numeric, continuous, "string" );
show(MetricCols);
//Get all unique combo of 2 Products
ColumnSplitByCombo = aslist( nchoosekMatrix(nitems(ColumnSplitBy), 2));
show (ColumnSplitByCombo);
//Create a combinaed datatable with stats (Table 2)
ow = dt << Oneway(
Y(Eval(MetricCols)),
X(Eval(SplitBy)),
Means and Std Dev(1),
SendToReport(
Dispatch(
{"Means and Std Deviations"},
"Std Dev Lower 95%",
NumberColBox,
{Visibility("Visible")}
),
Dispatch(
{"Means and Std Deviations"},
"Std Dev Upper 95%",
NumberColBox,
{Visibility("Visible")}
)
),
Invisible
);
tb = Report(ow[1])[Outline Box("Means and Std Deviations"), Table Box(1)];
dt2 = tb << Make Combined Data Table;
tb << close window;
//Create new table for the result, each row has a unique pair of Levels
dt3 = astable( nchoosekMatrix(nitems(ColumnSplitBy), 2), << column names({"x", "y"}) );
dt3 << new column ("first", character, << set values ( ColumnSplitBy[dt3:x << get values]));
dt3 << new column ("second", character, << set values ( ColumnSplitBy[dt3:y << get values]));
dt3 << delete columns (1::2);
//Create a nested list with each pair of levels
Listdt3 = aslist( nchoosekMatrix(nitems(ColumnSplitBy), 2));
show (Listdt3);
// I tried to use associate array() to match the level and name but couldn't make it work
// Loop over Metrics and perform these for each of them
// Concatenate results into single table
dt3 = As Table(NChooseK Matrix(N Items(ColumnSplitBy), 2), <<COLUMN names=""></COLUMN>Re: [JSL] Script per il test T a due lati su un gran numero di metricheCiao MRB3855,
Hai ragione, non volevo inserire troppe informazioni nel mio primo messaggio per concentrarmi sul problema del mio script, ma nel mio codice iniziale (che funziona per 2 livelli), ho impostato i limiti di equivalenza al 5% dell'intervallo [LSL;USL].
Naturalmente si tratta di un valore arbitrario che posso modificare se necessario.
Mi consente di esaminare centinaia di parametri e di contrassegnare quelli "Non equivalenti" in base a questo criterio, che in genere sono una dozzina.
Quindi da questo elenco posso eseguire un'analisi approfondita:
- Analisi della varianza
- TOST con un intervallo adeguato
- ecc...
Per quanto riguarda il secondo punto, se ho capito bene, suggerisci di eseguire la piattaforma TOST per ogni metrica e di selezionare i dati e inserirli in una tabella tramite Display Box()? Se è così, questa è effettivamente una possibile soluzione, ma preferirei eseguire io stesso i calcoli per comprendere il principio TOST e risparmiare anche un po' di tempo di elaborazione.
Spero che abbia senso:)
Grazie per l'aiuto
- Predicatore
Re: [JSL] Script per il test T a due lati su un gran numero di metricheCiao Mark,
Sì, all'inizio avevo pensato di usare la piattaforma TOST e di selezionare le statistiche con Display Box(), ma ho preferito un approccio diverso per calcolare ogni parametro individualmente per ottenere gli stessi risultati forniti dalla piattaforma.
A posteriori, forse sarebbe stato un approccio più rapido che reinventare la ruota, ma ormai ci ho investito così tanto tempo e sono così vicino a realizzarlo che potrei anche finire ciò che ho iniziato (nel modo più duro), haha!
Uno dei vantaggi è che ora capisco ogni passaggio del metodo TOST.
Grazie
- Predicatore
Re: [JSL] Script per il test T a due lati su un gran numero di metricheIo stesso userei molto probabilmente i loop, ma puoi farlo con alcune operazioni di matrice. Questo script richiederebbe una riscrittura per renderlo più facile da leggere, secondo me (variabili con nomi migliori, utilizzo del nome della tabella di output, chiusura delle tabelle non necessarie e pulizia generale)
Vedi altro...
Names Default To Here(1);
//Create table with random distribution (table 1)
dt = New Table("tabletest",
Add Rows(5000),
New Column("Product",
Character,
"Nominal",
formula("Product " || Char(Random Integer(1, 4)))
),
New Column("Metric1", Numeric, "Continuous", formula(Random Normal(10, 1))),
New Column("Metric2", Numeric, "Continuous", formula(Random Gamma(10, 1))),
New Column("Metric3", Numeric, "Continuous", formula(Random Gamma(10, 2))),
);
Column(dt, "Metric1") << set property("spec limits", {LSL(5), USL(25), Show Limits(0)});
Column(dt, "Metric2") << set property("spec limits", {LSL(0), USL(40), Show Limits(0)});
Column(dt, "Metric3") << set property("spec limits", {LSL(5), USL(40), Show Limits(0)});
SplitBy = "Product";
Summarize(ColumnSplitBy = by(Column(SplitBy)));
MetricCols = dt << Get Column Names(numeric, continuous, "string");
ColumnSplitByCombo = As List(NChooseK Matrix(N Items(ColumnSplitBy), 2));
//Create a combinaed datatable with stats (Table 2)
ow = dt << Oneway(
Y(Eval(MetricCols)),
X(Eval(SplitBy)),
Means and Std Dev(1),
SendToReport(
Dispatch({"Means and Std Deviations"}, "Std Dev Lower 95%", NumberColBox,
{Visibility("Visible")}
),
Dispatch({"Means and Std Deviations"}, "Std Dev Upper 95%", NumberColBox,
{Visibility("Visible")}
)
),
Invisible
);
tb = Report(ow[1])[Outline Box("Means and Std Deviations"), Table Box(1)];
dt2 = tb << Make Combined Data Table;
tb << close window;
//Create a nested list with each pair of levels
Listdt3 = As List(NChooseK Matrix(N Items(ColumnSplitBy), 2));
mcols = N Items(MetricCols);
l = Repeat(Listdt3, mcols);
m = J(N Items(l) / mcols, mcols) :*</img> (1::mcols);
mfinal = Sort Ascending(Shape(m, 1, N Items(l)));
dt3 = As Table(Matrix(l), <<COLUMN names=""></COLUMN>
</CODE><NOSCRIPT><CODE class=" language-jsl"><DIV class="lia-spoiler-noscript-container"><DIV class="lia-spoiler-noscript-content">I nomi predefiniti sono qui(1); //Crea una tabella con distribuzione casuale (tabella 1) dt = New Table("tabletest", Add Rows(5000), New Column("Product", Character, "Nominal", formula("Product " || Char(Random Integer(1, 4))) ), New Column("Metric1", Numeric, "Continuous", formula(Random Normal(10, 1))), New Column("Metric2", Numeric, "Continuous", formula(Random Gamma(10, 1))), New Column("Metric3", Numeric, "Continuous", formula(Random Gamma(10, 2))), ); Column(dt, "Metric1") << set property("spec limits", {LSL(5), USL(25), Show Limits(0)}); Colonna(dt, "Metrica2") << imposta proprietà("limiti di specifica", {LSL(0), USL(40), Mostra limiti(0)}); Colonna(dt, "Metrica3") << imposta proprietà("limiti di specifica", {LSL(5), USL(40), Mostra limiti(0)}); SplitBy = "Prodotto"; Riepilogo(ColonnaSplitBy = by(Colonna(SplitBy))); MetricaCols = dt << Ottieni nomi di colonne(numerico, continuo, "stringa"); ColonnaSplitByCombo = As List(NCooseK Matrix(N Items(ColonnaSplitBy), 2)); //Crea una tabella dati combinata con statistiche (Tabella 2) ow = dt << Oneway( Y(Eval(MetricCols)), X(Eval(SplitBy)), Means and Std Dev(1), SendToReport( Dispatch({"Means and Std Deviations"}, "Std Dev Lower 95%", NumberColBox, {Visibility("Visible")} ), Dispatch({"Means and Std Deviations"}, "Std Dev Upper 95%", NumberColBox, {Visibility("Visible")} ) ), Invisible ); tb = Report(ow[1])[Outline Box("Means and Std Deviations"), Table Box(1)]; dt2 = tb << Crea tabella dati combinati; tb << chiudi finestra; //Crea un elenco annidato con ogni coppia di livelli Listdt3 = As List(NChooseK Matrix(N Items(ColumnSplitBy), 2)); mcols = N Items(MetricCols); l = Repeat(Listdt3, mcols); m = J(N Items(l) / mcols, mcols) (1::mcols); mfinal = Sort Ascending(Shape(m, 1, N Items(l))); dt3 = As Table(Matrix(l), < <COLUMN names=""></COLUMN></DIV></DIV>
<P><SPAN class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jthi_1-1724774273332.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_1-1724774273332.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_1-1724774273332.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_1-1724774273332.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_1-1724774273332.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_1-1724774273332.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_1-1724774273332.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_1-1724774273332.png" style="width: 400px;"><span class="lia-inline-image-display-wrapper" image-alt="jthi_1-1724774273332.png" style="width: 400px;"><img src="https://us.v-cdn.net/6038925/uploads/images/67576i7A33F8F17FEAD03D/jthi_1-1724774273332.png" role="button" title="jthi_1-1724774273332.png" alt="jthi_1-1724774273332.png" /></span></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></P>
<P><SPAN class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jthi_2-1724774284315.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_2-1724774284315.png" style="width: 304px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_2-1724774284315.png" style="width: 304px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_2-1724774284315.png" style="width: 304px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_2-1724774284315.png" style="width: 304px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_2-1724774284315.png" style="width: 304px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_2-1724774284315.png" style="width: 304px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_2-1724774284315.png" style="width: 304px;"><span class="lia-inline-image-display-wrapper" image-alt="jthi_2-1724774284315.png" style="width: 304px;"><img src="https://us.v-cdn.net/6038925/uploads/images/67577i906F6E675ADD899F/jthi_2-1724774284315.png" role="button" title="jthi_2-1724774284315.png" alt="jthi_2-1724774284315.png" /></span></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></P>
<P><SPAN class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jthi_0-1724774190734.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_0-1724774190734.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_0-1724774190734.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_0-1724774190734.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_0-1724774190734.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_0-1724774190734.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_0-1724774190734.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="jthi_0-1724774190734.png" style="width: 400px;"><span class="lia-inline-image-display-wrapper" image-alt="jthi_0-1724774190734.png" style="width: 400px;"><img src="https://us.v-cdn.net/6038925/uploads/images/67575i9361F045B1E7C693/jthi_0-1724774190734.png" role="button" title="jthi_0-1724774190734.png" alt="jthi_0-1724774190734.png" /></span></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></P>
<P> </P> Re: [JSL] Script per il test T a due lati su un gran numero di metricheCiao Jarmo,
Grazie per la tua rapida risposta.
Questa linea non funziona
m = J(N Items(l) / mcols, mcols) (1::mcols);
Puoi spiegare a cosa serve?
Di solito non uso le matrici, ho provato a fare il debug ma non ci sono riuscito...
Grazie per l'aiuto
Re: [JSL] Script per il test T a due lati su un gran numero di metrichePer qualche motivo manca:*
m = J(N Items(l) / mcols, mcols) :*</img> (1 :: mcols);
Lo scopo è creare una matrice come questa

che poi converti in

utilizzando Forma.
Utilizzate anche i loop: sono generalmente molto più facili da leggere e capire rispetto ai bizzarri "trucchi" delle matrici.
Re: [JSL] Script per il test T a due lati su un gran numero di metricheCiao Jarmo,
Ho testato diverse versioni di questa riga, aggiungendo caratteri speciali che potrebbero perdersi nella traduzione, ma niente...
Questa linea non funziona dalla mia parte (sto usando JMP Pro 17)

Va bene, questa ottimizzazione tramite Matrix è davvero bella da avere. Come hai detto, anche usare i loop funziona, quindi andrò avanti così:)
Grazie ancora per aver trovato il tempo di aiutarmi (ancora una volta)!

- Predicatore
Re: [JSL] Script per il test T a due lati su un gran numero di metricheHo allegato la parte di codice che si interrompe nella community come screenshot

È la moltiplicazione elemento per elemento delle matrici E Mult()
@Ryan_Gilmore La comunità JMP sta mangiando:* (: * spazio aggiunto qui)
Blocco di codice JSL:
m = J(N Items(l) / mcols, mcols) :*</img> (1::mcols);
Testo:
m = J(N Elementi(l) / mcols, mcols):* (1::mcol);
Screenshot durante la modifica

Screenshot dall'anteprima

Re: [JSL] Script per il test T a due lati su un gran numero di metricheCiao @Voizingu Detto questo, sembra che tu abbia una soluzione che funziona per te. Eccellente! Tuttavia, per non perderlo, l'intervallo di confidenza dovrebbe essere un intervallo del 100(1-2alfa)%. Ad esempio, se vuoi che il tuo tasso di errore di tipo 1 sia del 5%, l'intervallo utilizzato per giudicare l'equivalenza dovrebbe essere un intervallo di confidenza del 90% (non del 95%). È un test biunilaterale ... ogni lato testato ad alfa = 0,05. Vedi allegato,