Aiuta a creare script di una finestra interattiva che si aggiorna in base alle scelte dell'utenteCarissimi,
Sto scrivendo uno script che verrà distribuito agli utenti della mia organizzazione per eseguire alcune semplici statistiche rapide per l'utente senza dover richiamare la piattaforma di distribuzione. Di seguito è riportato lo script con uno screenshot di ciò che ho attualmente, quindi un elenco delle cose con cui ho problemi. Gli utenti eseguiranno JMP 16.1, io utilizzo JMP Pro 16.0. Tutte le macchine sono macchine Windows 10, a 64 bit.
Lo scopo previsto dello script è mostrare le colonne numeriche (forse più tardi mi occuperò delle colonne categoriali) e, a seconda del pulsante di opzione selezionato, eseguirà alcune semplici statistiche e visualizzerà i risultati nella stessa finestra con una colonna denominata Stats per il tipo di statistica calcolata e Valori per i risultati di detti calcoli. La casella del pannello Risultati dovrebbe aggiornarsi alla selezione del pulsante di opzione dopo aver selezionato la colonna appropriata nella casella del pannello Seleziona colonna.
Attuale script JMP (per tua informazione, lo sto testando sul familiare file Big Class.jmp):
Names Default To Here( 1 );
//Clear Symbols();
//the width of the column list box in pixels
lbWidth = 100;
dt = Current Data Table();
//List of statistics to calculate
StatsListA = {"Mean", "Std Dev", "Max", "Min", "Range", "N"};
StatsListB = {"95% quantile", "50% quantile", "5% quantile"};
StatsListC = {};
//Expression to do math
MathA = Expr(
response_col = Column( dt, Eval( Eval Expr( Expr( ycols ) ) ) );
ymean = Col Mean( response_col );
ystdev = Col Std Dev( response_col );
ymin = Col Min( response_col );
ymax = Col Max( response_col );
yrange = ymax - ymin;
yN = Col Number( response_col );
NumResultsA = {ymean, ystdev, ymin, ymax, yrange, yN};
);
//Expresseion for other math
MathB = Expr(
);
ValueDlg = Expr(
nwin = New Window( "GUI for quick stats",
<<RETURN result=""></RETURN>
Questo è quello che ho finora:

Ecco l'elenco delle cose con cui ho problemi:
- La chiamata per Radio Box() elenca il nome della variabile locale "StatsListA", ecc. invece di elencare effettivamente le statistiche che verranno calcolate. Ad esempio, il primo pulsante di opzione dovrebbe avere dietro di sé il seguente elenco: Mean, Std Dev, Max, Min, Range, N. Questo dovrebbe essere anche per StatsListB e StatsListC (non ho ancora definito l'elenco C). Non sono sicuro di come farlo valutare l'elenco predefinito che creo nella parte superiore del codice JSL. Preferirei non dover scrivere ogni singolo elemento poiché potrei voler modificare gli elementi nell'elenco ed è più semplice modificare la variabile locale StatsListX invece di modificare ogni volta la chiamata Radio Box().
- In questo momento preferirei non elencare TUTTE le colonne, ma solo quelle numeriche. Quando cambio l'opzione in Col List Box() da Tutto a Numerico (con o senza ""), ottengo un elenco vuoto di colonne. Non riesco a capire perché questo sta accadendo, quando dovrebbe elencare solo le colonne numeriche quando ho definito quell'opzione.
- Questo è il più difficile, penso: come accennato in precedenza, vorrei che i risultati nella casella "Risultati" del pannello fossero aggiornati con una colonna a sinistra "Statistiche" (che elenca le statistiche di StatsListX e i risultati dei calcoli per quelli statistiche nella colonna di destra "Valori". Questo dovrebbe essere aggiornato con ogni clic di un pulsante di opzione. Quindi, se inizialmente stavi guardando :height, ma volessi guardare :weight, selezioneresti :weight e poi fare clic su uno dei pulsanti di opzione per ottenere il riepilogo statistico pertinente. Ho provato a seguire l'esempio Set Function mostrato qui, ma non ho avuto successo (non conosco molto bene la chiamata Set Function).

Expr() per MathA doveva essere richiamato chiudendo la finestra originale e aprendone una nuova con i risultati, ma dopo aver effettuato ulteriori ricerche nelle discussioni di JMP, ho scoperto che è possibile aggiornare i campi all'interno di una finestra esistente, che è il modo in cui preferisco affrontare questo problema. Quindi, so che la codifica originale nella parte superiore del mio codice non è il codice giusto per quello che intendo fare.
Qualsiasi aiuto su questo è molto apprezzato.
Grazie!,
DS
Ingegneria della qualità e dei processiRe: Guida allo scripting di una finestra interattiva che si aggiorna in base alle scelte dell'utenteÈ così carino. Grazie per questa discussione
Re: Guida allo scripting di una finestra interattiva che si aggiorna in base alle scelte dell'utenteCiao a tutti,
Vorrei ringraziarvi per le continue modifiche suggerite. Ho apportato alcune modifiche allo script e mi piace di più l'ultima versione modificata, quindi apprezzo molto i contributi degli altri. Lo script aggiornato verrà pubblicato alla fine di questa risposta. Questo nuovo script fornisce anche statistiche di riepilogo per i tipi di dati Character. Ho anche leggermente modificato la disposizione dei pannelli.
@jthi , Penso che i tuoi suggerimenti fossero molto buoni e li ho incorporati. Mi piacciono i nomi delle intestazioni colorate per le statistiche dei risultati. Inoltre, simile a cosa @ErraticAttack avevano nel loro codice, ho fatto in modo che le statistiche si aggiornassero selezionando una nuova colonna OPPURE selezionando un nuovo risultato numerico. Ho consentito ai risultati delle statistiche del personaggio di modificare la sua dimensione verticale perché potrebbero esserci molti livelli, come per la tabella dati Big Class.jmp. Le statistiche categoriche verranno aggiornate anche quando si passa a quel tipo di colonna, ma genererà un errore se viene selezionata la colonna dei caratteri e quindi qualcuno fa clic su un'opzione di statistica numerica. Ho mantenuto il suggerimento sulla larghezza in modo che la finestra non continuasse a modificare la dimensione della larghezza. Scusa @ErraticAttack , a questo punto non ho molta familiarità con la definizione di nuovi spazi dei nomi e con il modo in cui hai modificato il codice. Sembra molto utile e un buon modo per affrontare le cose, ho solo bisogno di imparare come farlo correttamente.
Sono sicuro che ci siano altri suggerimenti là fuori su come migliorarlo, soprattutto l'estetica. Se è così, per favore pubblicalo, ma assicurati di taggarmi così so che c'è stato un aggiornamento a questa discussione. Grazie ancora a tutti per i miglioramenti suggeriti.
Grazie!,
DS
di seguito
//GUI for quickly reporting statistics written by D. Schmidt, ver1.5
//Thanks to JMP User community members: jthi, ian_jmp, and ErraticAttach for helpful suggested changes.
Names Default To Here( 1 );
Clear Symbols();
//the width of the column list box in pixels
lbWidth = 217;
dt = Current Data Table();
//dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
//List of statistics to calculate
StatsList1 = {"µ", "σ", "Max", "Min", "Range(Δ)", "N"};
StatsList2 = {"Quantiles", "5%", "25%", "50%", "75%", "95%"};
StatsList3 = {"N", "N Missing", "N 0", "Prop 0", "Prop non-0"};
maxStatCount = Max( N Items( StatsList1 ), N Items( StatsList2 ), N Items( StatsList3 ) );
//RadioBox() arguments
rbArg = Eval List( {Concat Items( StatsList1, ", " ), Concat Items( StatsList2, ", " ), Concat Items( StatsList3, ", " )} );
rbcArg = {"Select for categorical columns"};
//Statistics to Calculate
statMean = Expr( Col Mean( tempCol ) );
statStd = Expr( Col Std Dev( tempCol ) );
statMax = Expr( Col Max( tempCol ) );
statMin = Expr( Col Min( tempCol ) );
statRange = Expr(
Col Max( tempCol ) - Col Min( tempCol )
);
statN = Expr( Col Number( tempCol ) );
statQ95 = Expr(
Col Quantile( tempCol, 0.05 )
);
statQ75 = Expr(
Col Quantile( tempCol, 0.25 )
);
statQ50 = Expr(
Col Quantile( tempCol, 0.5 )
);
statQ25 = Expr(
Col Quantile( tempCol, 0.75 )
);
statQ5 = Expr(
Col Quantile( tempCol, 0.95 )
);
statMiss = Expr(
Col N Missing( tempCol )
);
statZero = Expr(
N Items( Loc( tempCol << get as matrix, 0 ) )
);
statProp0 = Expr( statZero / statN );
statPropn0 = Expr( 1 - statProp0 );
CatStats = Expr(
coltype = tempCol << Get Data type;
If( coltype == "Character",
catdist = dt << Distribution( Nominal Distribution( Column( tempCol ) ), Invisible );
rpt_catdist = catdist << Report;
lvl = rpt_catdist[String Col Box( 1 )] << Get;
Count = rpt_catdist[Number Col Box( 1 )] << Get;
Prob = rpt_catdist[Number Col Box( 2 )] << Get;
SummNMiss = rpt_catdist[List Box( 7 )][2] << Get Text;
SummLvl = rpt_catdist[List Box( 8 )][1] << Get text;
numNMiss = Num( SummNMiss );
numLvl = Num( SummLvl );
catdist << Close Window;
);
Insert Into( lvl, {"N Missing", "N Levels"} );
Insert Into( Count, numNMiss );
Insert Into( Count, numLvl );
);
//List for results
StatList = Eval List( {StatsList1, StatsList2, StatsList3} );
StatListRes1 = Expr(
Eval List( {statMean, statStd, statMax, statMin, statRange, statN} )
);
StatListRes2 = Expr(
Eval List( {., statQ95, statQ75, statQ50, statQ25, statQ5} )
);
StatListRes3 = Expr(
Eval List( {statN, statMiss, statZero, statProp0, statPropn0} )
);
StatListRes = Expr(
Eval List( {StatListRes1, StatListRes2, StatListRes3} )
);
//User window
ValueDlg = Expr(
nwin = New Window( "GUI for quick stats",
<<RETURN result=""></RETURN>
Re: Guida allo scripting di una finestra interattiva che si aggiorna in base alle scelte dell'utenteCIAO @jimloughlin ,
Penso che fosse solo un codice di debug @jthi stava usando quando ha fornito le modifiche suggerite al mio codice originale che ho pubblicato. Ne sto pubblicando uno aggiornato che tiene conto di alcune modifiche suggerite da altre persone che hanno scritto su questo thread. Ti taggherò quando pubblicherò lo script aggiornato. Funziona perfettamente con la tabella dati Big Class.jmp.
Grazie!,
DS
Re: Guida allo scripting di una finestra interattiva che si aggiorna in base alle scelte dell'utenteMetto qui i miei due centesimi.Spesso è meglio separare il più possibile lo script in unità o funzioni logicamente isolate.A tal fine, trovo molto meglio rimuovere la logica dall'albero di visualizzazione e appiattire il più possibile le definizioni delle funzioni.
Nella mia soluzione di esempio di seguito vedrai che tutte le funzioni hanno come ambito il file se stesso namespace e che la prima riga in ciascuna funzione abbia come ambito il file se stesso spazio dei nomi.In pratica quello che ho fatto è creare un wrapper di meta-programmazione che lo faccia automaticamente in modo tale da non dover definire esplicitamente il se stesso spazio dei nomi o includere il file self = Spazio dei nomi("nome") linea come primo argomento di ciascuna funzione.Se crei molte GUI interattive potresti voler fare qualcosa di simile in quanto risparmia una grande quantità di lavoro.Ciò ha anche il vantaggio di non dover racchiudere lo script in un file Eval( Eval Expr( "<CODICE>" ) )</CODICE> bloccare.
Inoltre, se si segue questa strada, trovo più semplice produrre un wrapper per le caselle di visualizzazione integrate che possano chiamare direttamente il se stesso funzioni e non avere la necessità di mettere così tanta piastra all'interno del << Imposta funzione() messaggi.
/* quick stats */
self = New Namespace();
self:tool name = "Quick Stats";
Eval( Eval Expr(
self:initialize = Function( {}, // called before the display tree is generated
self = Namespace( Expr( self << Get Name ) );
self:table = Current Data Table();
self:radio inputs = {
"Mean, Std Dev, Max, Min, Range, N",
"Quantiles: 0.05, 0.25, 0.50, 0.75, 0.95",
"N, N Missing, N Zero, Prop 0, Prop non-0"
};
self:stat list = {
{"Mean", "Std Dev", "Max", "Min", "Range", "N"},
{"5%", "25%", "50%", "75%", "95%"},
{"N", "N Missing", "N Zero", "Prop 0", "Prop non-0"}
};
1
);
self:content = Function( {}, // holds the display tree
self = Namespace( Expr( self << Get Name ) );
self:container = H Splitter Box(
V List Box(
H List Box(
Lineup Box( N Col( 1 ), Spacing( 0 ),
Spacer Box( <<SET auto="" stretching=""></SET>self:window << Update Window;
self:finalize();
) );
self << Get Name;
Re: Guida allo scripting di una finestra interattiva che si aggiorna in base alle scelte dell'utenteQuando eseguo statsstart.jcl, ottengo il seguente errore:
Nome non risolto: tempCol{1} nell'accesso o nella valutazione di 'tempCol' , tempCol/*###*/
Forse perché sto utilizzando la versione 13.2.1?
Re: Guida allo scripting di una finestra interattiva che si aggiorna in base alle scelte dell'utenteDopo aver fatto in modo che lo script funzioni per lo più come desideri, ci sono un paio di cose visive che prenderei in considerazione:
- La dimensione della tabella cambia e fa "rimbalzare" leggermente la finestra
- Se l'utente non ha selezionato alcuna colonna, si verificherà un errore
- Se non sono aperte tabelle dati, è possibile interrompere l'esecuzione dello script e informare l'utente
- Se l'utente modifica la colonna nella casella di riepilogo Col, potresti ricalcolare le statistiche con la selezione corrente di Radio Box OPPURE impostare la tabella vuota.
Un paio di idee:
- Per la casella del pannello Risultati. È possibile utilizzare Imposta larghezze per impedire alla tabella di modificare le dimensioni orizzontali e il segnaposto nascosto String Col Box con dimensioni dell'elenco predefinite per impedire modifiche delle dimensioni verticali
- Selezionare la casella del pannello Colonne. È possibile aggiungere Max Selected(1) per impedire all'utente di selezionare più colonne.
- Scegli la casella del pannello Statistiche rapide. Una sorta di "gestione degli errori" se l'utente non ha selezionato alcuna colonna.
Script completo con alcune modifiche:
Visualizza altro...
Re: Guida allo scripting di una finestra interattiva che si aggiorna in base alle scelte dell'utenteCIAO @jthi E @ian_jmp ,
Grazie ad entrambi per il vostro grande aiuto! Grazie per gli ultimi due suggerimenti finali @jthi , sono riuscito a superare il "problema" alfabetico della matrice associativa. Mi piace la potenza degli AA, vedo dove possono tornare utili, ma ho bisogno che venga mantenuto un certo ordine a causa degli utenti.
Sono riuscito ad apportare le modifiche con il suggerimento degli elenchi e il tuo suggerimento per il problema del conteggio zero che ho avuto. Grazie! Il codice funziona come previsto, ora dovrò espanderlo per creare colonne categoriche e quindi esaminare i miei utenti per vedere quale elenco effettivo di statistiche hanno bisogno.
Grazie ancora per tutto il vostro aiuto! Il codice di funzionamento (almeno per le colonne numeriche) è riportato di seguito.
Grazie!,
DS
Names Default To Here( 1 );
Clear Symbols();
//the width of the column list box in pixels
lbWidth = 205;
dt = Current Data Table();
//dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
//List of statistics to calculate
StatsList1 = {"Mean", "Std Dev", "Max", "Min", "Range", "N"};
StatsList2 = {"Quantiles", "5%", "25%", "50%", "75%", "95%"};
StatsList3 = {"N", "N Missing", "N Zero", "Prop 0", "Prop non-0"};
//Statistics to Calculate
statMean = Expr( Col Mean( tempCol ) );
statStd = Expr( Col Std Dev( tempCol ) );
statMax = Expr( Col Max( tempCol ) );
statMin = Expr( Col Min( tempCol ) );
statRange = Expr(
Col Max( tempCol ) - Col Min( tempCol )
);
statN = Expr( Col Number( tempCol ) );
statQ95 = Expr(
Col Quantile( tempCol, 0.05 )
);
statQ75 = Expr(
Col Quantile( tempCol, 0.25 )
);
statQ50 = Expr(
Col Quantile( tempCol, 0.5 )
);
statQ25 = Expr(
Col Quantile( tempCol, 0.75 )
);
statQ5 = Expr(
Col Quantile( tempCol, 0.95 )
);
statMiss = Expr(
Col N Missing( tempCol )
);
statZero = Expr(
N Items( Loc( tempCol << get as matrix, 0 ) )
);
statProp0 = Expr( statZero / statN );
statPropn0 = Expr( 1 - statProp0 );
//RadioBox() argument
rbArg = Eval List( {Concat Items( StatsList1, ", " ), Concat Items( StatsList2, ", " ), Concat Items( StatsList3, ", " )} );
//List for results
StatList = Eval List( {StatsList1, StatsList2, StatsList3} );
StatListRes1 = Expr(
Eval List( {statMean, statStd, statMax, statMin, statRange, statN} )
);
StatListRes2 = Expr(
Eval List( {., statQ95, statQ75, statQ50, statQ25, statQ5} )
);
StatListRes3 = Expr(
Eval List( {statN, statMiss, statZero, statProp0, statPropn0} )
);
StatListRes = Expr(
Eval List( {StatListRes1, StatListRes2, StatListRes3} )
);
//User window
ValueDlg = Expr(
nwin = New Window( "GUI for quick stats",
<<RETURN result=""></RETURN>Re: Guida allo scripting di una finestra interattiva che si aggiorna in base alle scelte dell'utente1. A causa dell'utilizzo dell'array associativo le statistiche verranno riordinate. Potresti semplicemente utilizzare elenchi e modificare i riferimenti per utilizzare gli indici
2. La modifica del modo in cui calcoli i valori 0 potrebbe funzionare. Potresti ad esempio utilizzare l'esempio Loc() con N Items():
statZero = Expr(N Items(Loc(tempCol << get as matrix, 0)));

Re: Guida allo scripting di una finestra interattiva che si aggiorna in base alle scelte dell'utenteCIAO @jthi E @ian_jmp ,
Grazie mille per il rapido feedback! I tuoi suggerimenti hanno funzionato benissimo e ho potuto fare molti più progressi. Ora sto riscontrando problemi solo con due cose probabilmente molto semplici, includo il codice aggiornato di seguito. Per tua informazione, ho cancellato alcuni valori in :height e ho aggiunto alcuni zeri in :height per testarlo
Problemi:
- Quando elenca le statistiche le fa in ordine alfabetico, vorrei mantenere l'ordine che ho definito nelle mie liste, è possibile?
- Sto cercando di calcolare la proporzione zero e diversa da zero contando prima il numero di zeri. Sfortunatamente, non funziona nel modo giusto. Posso inserire il riepilogo all'interno di un Expr(), ma poi non sono in grado di definire l'array associativo e non ottengo i calcoli successivi corretti. Sono sicuro che esiste un modo più semplice per farlo, ma non sono riuscito a trovare alcun comando diretto in JSL per contare solo zeri. Ho inserito manualmente 5 valori mancanti e 7 valori zero. Quindi, l'elica diversa da zero dovrebbe essere 0,8 e l'elica zero dovrebbe essere 0,2.
Names Default To Here( 1 );
Clear Symbols();
//the width of the column list box in pixels
lbWidth = 205;
dt = Current Data Table();
//dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
//List of statistics to calculate
StatsListA = {"Mean", "Std Dev", "Max", "Min", "Range", "N"};
StatsListB = {"Quantiles", "5%", "25%", "50%", "75%", "95%"};
StatsListC = {"N", "N Missing", "N Zero", "Prop 0", "Prop non-0"};
//RadioBox() argument
rbArg = Eval List( {Concat Items( StatsListA, ", " ), Concat Items( StatsListB, ", " ), Concat Items( StatsListC, ", " )} );
//Statistics to Calculate
statMean = Expr( Col Mean( tempCol ) );
statStd = Expr( Col Std Dev( tempCol ) );
statMax = Expr( Col Max( tempCol ) );
statMin = Expr( Col Min( tempCol ) );
statRange = Expr(
Col Max( tempCol ) - Col Min( tempCol )
);
statN = Expr( Col Number( tempCol ) );
statQ95 = Expr(
Col Quantile( tempCol, 0.05 )
);
statQ75 = Expr(
Col Quantile( tempCol, 0.25 )
);
statQ50 = Expr(
Col Quantile( tempCol, 0.5 )
);
statQ25 = Expr(
Col Quantile( tempCol, 0.75 )
);
statQ5 = Expr(
Col Quantile( tempCol, 0.95 )
);
statMiss = Expr(
Col N Missing( tempCol )
);<BR /><BR />//Here's where I'm having trouble with the N Zero and proportions zero and non-zero.
Expr(
Summarize( dt, eg = By( tempCol ), em = Count( tempCol ) )
);
PropTemp1 = Expr(
Associative Array( eg, em )
);
statZero = Expr( PropTemp1["0"] );
statProp0 = Expr( statZero / statN );
statPropn0 = Expr( 1 - statProp0 );
maths = Associative Array();
maths["StatListA"] = Associative Array( StatsListA, {statMean, statStd, statMax, statMin, statRange, statN} );
maths["StatListB"] = Associative Array( StatsListB, {., statQ95, statQ75, statQ50, statQ25, statQ5} );
maths["StatListC"] = Associative Array( StatsListC, {statN, statMiss, statZero, statProp0, statPropn0} );
rbOptions = maths << Get Keys;
//User window
ValueDlg = Expr(
nwin = New Window( "GUI for quick stats",
<<RETURN result=""></RETURN>
Grazie ancora per il tuo aiuto finora e spero che tu possa aiutarmi con queste altre piccole cose.
Grazie!,
DS
Re: Guida allo scripting di una finestra interattiva che si aggiorna in base alle scelte dell'utentePer quanto riguarda il punto 1., e aggiungo solo qualcosa alla risposta di @jthi , tu puoi fare:
Names Default To Here( 1 );
//the width of the column list box in pixels
lbWidth = 100;
dt = Open("$SAMPLE_DATA/Big Class.jmp");
//List of statistics to calculate
StatsListA = {"Mean", "Std Dev", "Max", "Min", "Range", "N"};
StatsListB = {"95% quantile", "50% quantile", "5% quantile"};
//RadioBox() argument
rbArg = EvalList({ConcatItems(StatsListA, ", "), ConcatItems(StatsListB, ", ")});
//Window
New Window( "GUI for quick stats",
Panel Box( "Select Columns", ColListData = Col List Box( dt, all, <<SET data="https://community.jmp.com/" type=""></SET>
Re: Guida allo scripting di una finestra interattiva che si aggiorna in base alle scelte dell'utenteHo fatto alcuni test rapidi e ho allegato lo script. Ha possibili idee su come affrontare questo problema, ma potrebbero non essere le soluzioni migliori.
1. Gestito con matrici ed espressioni associative.
2. Ho dovuto usare una sintassi strana per questo ColListData = Col List Box(dt, All, <
3. Set Function gestisce questo con Evals.
Lo script allegato darà la migliore idea di come mi sono avvicinato a questo per ora.
