Scripting JSL per l'assegnazione dinamica delle colonne nel generatore di graficiSto cercando di creare uno script di sessione per generare grafici utilizzando Graph Builder di JMP. Tuttavia, si presenta una difficoltà perché il numero di colonne nei miei dati varia a seconda del periodo ogni volta che i dati vengono aggiornati, il che rende necessario modificare manualmente lo script di Graph Builder per ogni aggiornamento.
To address this, I am considering a method where column names are prefixed (e.g., A_, B_, C_). This would allow me to dynamically assign columns: for instance, columns prefixed with A_ could be directed to the Local Data Filter, those with B_ to the Column Switcher, and so forth.
Vorrei sapere come implementare questo approccio in JSL (JMP Scripting Language), dato che non sono riuscito a scrivere uno script efficace. Hai menzionato di avere in mente una bozza incompleta di JSL, ma non l'hai inclusa nella tua richiesta. Se potessi fornirmela, sarei lieto di aiutarti a perfezionarla o a suggerirti una soluzione.
Sto riscontrando anche il seguente errore.→[Per ogni , Argomento non valido (colName), Per ogni/*###*/(colName, columnNames,... L'argomento deve essere un elenco. ]
dt = Current Data Table();
A_list = {};
B_list = {};
columnNames = As List(dt << Get Column Names("String"));
For Each(colName, columnNames,<BR />
If(Contains(colName, "A_"),
Insert Into(A_list, colName)
);
If(Contains(colName, "B_"),
Insert Into(B_list, colName)
);
);
Graph Builder(
Variables(
X( :point ),
Y( :avg ),
Y( :stddev ),
Page( :category ),
Color(B_list[1])
),
Elements(
Position( 1, 1 ),
Points( X, Y( 1 ), Legend( 27 ) ),
Line( X, Y( 2 ), Y( 3 ), Color( 0 ), Legend( 29 ) )
),
Elements(
Position( 1, 2 ),
Points( X, Y( 1 ), Legend( 28 ) ),
Line( X, Y( 2 ), Y( 3 ), Color( 0 ), Legend( 31 ) )
),
Local Data Filter(
Conditional,
Add Filter(
columns( A_list ),
Display( A_list[1], N Items( 7 ), Find( Set Text( "" ) ) ),
Display( A_list[2], N Items( 7 ) ),
Display( :key, N Items( 12 ) )
)
),
Column Switcher(
:msr_dt,
B_list
)
);
Automazione e scriptingOggetto: Scripting JSL per l'assegnazione dinamica delle colonne nel generatore di graficiHai considerato l'utilizzo di tag di colonna per "raggruppare" le colonne?
Questa soluzione potrebbe offrire una funzionalità simile, consentendo persino la sovrapposizione di "gruppi".
Qualcosa del tipo:
Names Default to Here(1);
dt = Open( "$SAMPLE_DATA/Big Class Families.jmp" );
dt:sex << setProperty( "Tags", {"pick"} );
dt:height << setProperty( "Tags", {"pick"} );
dt:weight << setProperty( "Tags", {"pick"} );
cols = dt << Get Tagged Columns( "pick" );
dt << Distribution( Column( Eval(cols) ));
a proposito, è per ogni ({col}, cols, body)
Oggetto: Scripting JSL per l'assegnazione dinamica delle colonne nel generatore di grafici
Grazie per la tua risposta, Hogi.
Non avevo considerato i tag di colonna. Proverò a rivedere lo script utilizzando nuovamente i tag di colonna.
Risponderò dopo averlo fatto.
Oggetto: Scripting JSL per l'assegnazione dinamica delle colonne nel generatore di graficiA seconda del caso d'uso, si potrebbero utilizzare tag come quelli già suggeriti, proprietà di colonna personalizzate, nomi di colonna con prefisso, gruppi di colonne, ecc. Tutte le opzioni presentano vantaggi e svantaggi.
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Semiconductor Capability.jmp");
collist = dt << Get Column Names("String");
npn_cols = Filter Each({colname}, collist, Starts With(colname, "NPN"));
pnp_cols = Filter Each({colname}, collist, Starts With(colname, "PNP"));
gb = dt << Graph Builder(
Variables(X(:SITE), Y(:IVP1), Color(pnp_cols[1])),
Elements(
Position(1, 1),
Points(X, Y(1), Legend(27))
),
Elements(
Position(1, 2),
Points(X, Y(1), Legend(28)),
Line(X, Y(2), Y(3), Color(0), Legend(31))
)
);
filter_cols = npn_cols[1::2];
Insert Into(filter_cols, "SITE");
ldf = gb << Local Data Filter(
Conditional,
Add Filter(
columns(Eval(filter_cols)),
Display(filter_cols[1]),
Display(filter_cols[2]),
Display(filter_cols[3])
)
);
cw = gb << Column Switcher(pnp_cols[1], pnp_cols);
Inoltre... si tratta di una sorta di ibrido tra una domanda della community e un prompt di LLM (siamo tutti umani qui nella Community, si spera)?
Oggetto: Scripting JSL per l'assegnazione dinamica delle colonne nel generatore di graficiVi prego di scusare la mia risposta in giapponese (ho pensato che in questo modo avrei espresso meglio le mie vere intenzioni).
Stiamo ora condividendo con la community i casi in cui le domande poste a JMP learnBot non hanno trovato risposta.
In definitiva, utilizzo questa community per migliorare le mie competenze di sceneggiatura ricevendo consigli e indicazioni sui metodi di scrittura da persone esperte, e anche per contribuire allo sviluppo delle competenze degli altri utenti di JMP intorno a me.
Mi dispiace molto, perché temo di aver offeso jthi, che risponde sempre con tanta gentilezza alle mie domande. Se c'è stato qualcosa di scortese o inappropriato nel modo in cui ho posto la domanda, le sarei grato se potesse farmelo notare per il futuro.
Oggetto: Scripting JSL per l'assegnazione dinamica delle colonne nel generatore di graficiNon mi sono offeso per il tuo post, ma mi ha piuttosto spiazzato perché mi è sembrato che ci venisse suggerito di rispondere. Ti consiglierei di separare il messaggio di richiesta, se ne hai utilizzato uno.
LearnBot non è molto efficace con JSL perché non è configurato per questo scopo. Assistant potrebbe essere leggermente migliore, ma potresti ottenere risultati migliori se fornissi istruzioni a LLM (come Claude, preferibilmente uno a cui la tua azienda ha accesso) in modo che capisca cosa deve fare (JSL).
Oggetto: Scripting JSL per l'assegnazione dinamica delle colonne nel generatore di graficiCome ha fatto notare Jthi, non avevo fatto una netta distinzione tra le richieste per LLM e i post per la community di utenti JMP.
In futuro, esaminerò attentamente il contenuto per determinare se si tratta di una domanda per LLM o di un post appropriato per la community di utenti JMP. Grazie per aver evidenziato aspetti importanti da tenere a mente per una comunicazione più fluida.
Confido nel vostro continuo supporto.
Oggetto: Scripting JSL per l'assegnazione dinamica delle colonne nel generatore di graficiNel caso in cui stessi cercando di capire come far funzionare lo script, ecco una versione aggiornata che potrebbe esserti d'aiuto. Ho commentato alcune sezioni che ho modificato; tieni presente che la più complessa prevede l'inserimento di un elenco di colonne nel filtro dati locale, il che ha attivato le funzioni Eval( Eval Insert() ). Potresti consultare la sezione "Inserire un'espressione in un'altra usando Eval Insert, Eval Expr, Parse e Substitute" per vedere le diverse opzioni disponibili.
Names default to here(1);
Random reset(1);
msr_dt = New Table( "Example Data",
Add Rows( 200 ),
New Column( "A_1", Character, "Nominal", Formula( if(random uniform(1)<0.2,"",Substr( "ABC", floor(Random uniform( 4 )),1) ))),
New Column( "A_2", Character, "Nominal", Formula( if(random uniform(1)<0.2,"",Substr( "DEF", floor(Random uniform( 4 )),1) ))),
New Column( "B_1", Character, "Nominal", Formula( if(random uniform(1)<0.2,"",Substr( "GHI", floor(Random uniform( 4 )),1) ))),
New Column( "B_2", Character, "Nominal", Formula( if(random uniform(1)<0.2,"",Substr( "JKL", floor(Random uniform( 4 )),1) ))),
New Column( "point", Numeric, "Continuous", Format( "Best", 12 ), Formula( Row() ) ),
New Column( "avg", Numeric, "Continuous", Format( "Best", 12 ), Formula( Random Normal( 5 ) ) ),
New Column( "stddev", Numeric, "Continuous", Format( "Best", 12 ), Formula( Random Normal( 0.5 ) ) ),
New Column( "category", Character, "Nominal", Formula( Char( Floor( Row() / 101 ) ) ), Set Selected ),
New Column( "key", Character, "Nominal", Formula( Substr( "abcdefghijklmnopqrstufwxyz", floor(Random uniform( 27 )),1) )),
);
A_list = {};
B_list = {};
columnNames = As List(msr_dt << Get Column Names("String"));
For Each({colName},columnNames, // change here - note brackets
If(Contains(colName, "A_"),
Insert Into(A_list, colName)
);
If(Contains(colName, "B_"),
Insert Into(B_list, colName)
);
);
Eval(Eval expr(
Graph Builder(
Variables(
X( :point ),
Y( :avg ),
Y( :stddev ),
Page( :category ),
Color(B_list[1])
),
Show Control Panel( 0 ),
Elements(
Position( 1, 1 ),
Points( X, Y( 1 ), Legend( 27 ) ),
Line( X, Y( 2 ), Y( 3 ), Color( 0 ), Legend( 29 ) )
),
Elements(
Position( 1, 2 ),
Points( X, Y( 1 ), Legend( 28 ) ),
Line( X, Y( 2 ), Y( 3 ), Color( 0 ), Legend( 31 ) )
),
Local Data Filter(
Conditional,
Add Filter(
columns( Expr( A_list || {"key"} ) ), //this needs to be evaluated before the graph builder function is called
Display( A_list[1], N Items( 7 ) ), //removed the find term
Display( A_list[2], N Items( 7 ) ),
Display( :key, N Items( 12 ) )
)
),
Column Switcher(
B_list[1], // added reference to specific column here - was the data table
B_list
)
)
));
Oggetto: Scripting JSL per l'assegnazione dinamica delle colonne nel generatore di graficiSono un principiante di JSL, quindi perdonatemi se questa domanda è già stata posta e ha già ricevuto risposta.
Quello che vorrei fare è modificare lo script Graph Builder sopra riportato per tracciare le colonne IVP rispetto alle colonne NPN utilizzando i colori delle colonne PNP. Allego lo script modificato (Multiple Column Switcher.jsl) con 3 selettori di colonna. Devo selezionare manualmente le combinazioni di colonne IVP, NPN e PNP che desidero. Se so che le colonne IVP, NPN e PNP sono tutte mappate uno a uno (ad esempio IVP3 rispetto a NPN3 e PNP3), come posso ottenere questo risultato con un singolo selettore di colonna?
Oggetto: Scripting JSL per l'assegnazione dinamica delle colonne nel generatore di graficiAvevo una versione semplificata di questo nella mia presentazione di suggerimenti e trucchi al Discovery Summit ( Salta, salta e fai JMP a ritmo serrato: consigli di JMP in pillole da un super utente (2026-EU-30MP-2767) , suggerimento "Selettori di colonne per tutti (Selettori di colonne multipli)")
Questo è un modo piuttosto semplice per farlo (si noti che NPN ha più colonne rispetto agli altri, quindi in tal caso verrà utilizzata la colonna errata).
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Semiconductor Capability.jmp");
collist = dt << Get Column Names("String");
npn_cols = Filter Each({colname}, collist, Starts With(colname, "NPN"));
pnp_cols = Filter Each({colname}, collist, Starts With(colname, "PNP"));
ivp_cols = Filter Each({colname}, collist, Starts With(colname, "IVP"));
gb = dt << Graph Builder(
Variables(X(:NPN1), Y(:IVP1), Color(pnp_cols[1])),
Elements(
Position(1, 1),
Points(X, Y(1), Legend(27))
),
Elements(
Position(1, 2),
Points(X, Y(1), Legend(28)),
Line(X, Y(2), Y(3), Color(0), Legend(31))
)
);
cw1 = gb << Column Switcher(npn_cols[1], npn_cols);
cw2 = gb << Column Switcher(pnp_cols[1], pnp_cols);
cw3 = gb << Column Switcher(ivp_cols[1], ivp_cols);
Eval(EvalExpr(
post = Function({previousColumn, currentColumn, switcher},
c2 = Substitute((currentColumn << get name), "NPN", "PNP");
c3 = Substitute((currentColumn << get name), "NPN", "IVP");
Expr(cw2) << Set Current(c2);
Expr(cw3) << Set Current(c3);
);
));
handler = cw1 << Make Column Switch Handler(post);
// might want to hide other column switchers
cw_obs = (Report(gb) << Top Parent) << XPath("//ColumnSwitcherContextOutlineBox");
cws = cw_obs << Get Scriptable Object;
cw_obs[2] << Visibility("Collapse");
cw_obs[3] << Visibility("Collapse");
Write();
Le tabelle di dati impilate e i filtri di dati locali possono essere un'ottima opzione anche per cose come questa