<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />Ciao a tutti,
Attualmente sto costruendo uno strumento di analisi dei dati utilizzando JMP. Fondamentalmente utilizzeremo JMP per consentire al nostro cliente di interagire con l'output della simulazione che è stato generato utilizzando altri software.
L'output della simulazione è archiviato in più tabelle con caratteristiche diverse ma con gli stessi identificatori. Ad esempio, una tabella contiene i valori di output globalmente associati a 1 replica di simulazione, una tabella diversa contiene l'output associato a ciascun agente presente in una replica di simulazione (e quindi ha più righe per replica) e un'altra tabella potrebbe contenere l'output per ogni fase temporale di ogni replica di simulazione (includendo quindi molte righe per replica). Ciò che tutte le tabelle hanno in comune sono le colonne con identificatori e parametri di input.
Ora la sfida: vorrei essere in grado di creare un filtro dati che filtri tutte le tabelle di dati contemporaneamente (ovviamente questo viene fatto sulla base delle informazioni che condividono (ad esempio un identificatore)). Il mio obiettivo di fondo è organizzare i dati nel formato tabella più conveniente pur essendo in grado di presentare dinamicamente informazioni da tabelle diverse utilizzando grafici, ecc.
Qualsiasi pensiero tu possa avere, per favore fatemelo sapere!
Grazie in anticipo
Il JSL a:
http://support.sas.com/demosdownloads/downarea_t4.jsp?productID=109646
è piuttosto vecchio e (per fortuna!) Obsoleto poiché abbiamo aggiunto il "gestore dello stato della riga" (in JMP 10 credo). Questo ha una varietà di usi e il codice seguente mostra come potresti sfruttarlo in questo caso.
// ian.cox@jmp.com : 03 novembre 2014
// Dimostrazione di come collegare più tabelle figlio a una tabella padre utilizzando un gestore di stato riga
NomiDefaultToHere ( 1 ) ;
// Crea delle tabelle da usare
dt1 = Nuova tabella ( "Tabella 1" ,
Nuova colonna ( "ID" , Numerico , Continuo , I valori ((( 1 :: 10 ) ` )) ,
Nuova colonna ( "Risposta" , Numerico , Continuo , Formula ( CasualeNormale ( 0 , 1 )))
) ;
dt2 = Nuova tabella ( "Tavolo 2" ,
Nuova colonna ( "ID" , Numerico , Continuo , Formula ( Intero casuale ( 1 , 5 ))) ,
Nuova colonna ( "Attributo 2" , Numerico , Continuo , Formula ( Intero casuale ( 0 , 10 ))) ,
Aggiungi righe ( 20 )
) ;
dt3 = Nuova tabella ( "Tabella 3" ,
Nuova colonna ( "ID" , Numerico , Continuo , Formula ( Intero casuale ( 1 , 11 ))) ,
Nuova colonna ( "Attributo 3" , Numerico , Continuo , Formula ( Intero casuale ( 0 , 100 ))) ,
Aggiungi righe ( 30 )
) ;
// Funzione utile:
// Data una tabella di dati, una colonna in essa contenuta e alcuni valori in quella colonna, seleziona tutte le righe corrispondenti.
// Necessità di consentire che 'col' sia numerico (carattere), nel qual caso 'vals' è una matrice (è un elenco).
selezionare Righe corrispondenti =
Funzione ({ dt , col , val } ,
righe2seleziona = [] ;
Se ( Is Matrix ( val ) ,
// 'col' è numerico
Per ( io = 1 , io <= Ora ( val ) , io ++,
righe2seleziona = VConcat ( righe2seleziona , dt << GetRowsWhere ( col == val [ io ])) ;
)
,
// 'col' è un carattere
Per ( io = 1 , io <= NI articoli ( val ) , io ++,
righe2seleziona = VConcat ( righe2seleziona , dt << GetRowsWhere ( col == val [ io ])) ;
)
) ;
dt << Seleziona Righe ( righe2seleziona ) ;
) ;
// Crea un gestore dello stato di riga da assegnare alla tabella 'master' (dt1). Consenti selezioni multiple di righe.
propagateSelectionToOtherTables =
Funzione ({ X } ,
// Ottieni le righe che sono state selezionate
righe selezionate = dt1 << GetSelectedRows ;
Se ( Ora ( righe selezionate ) > 0 ,
// Ottieni gli ID corrispondenti
ID = dt1 : ID [ righe selezionate ] ;
// Seleziona le righe corrispondenti in dt2
selezionare Righe corrispondenti ( dt2 , espr ( : ID ) , ID ) ;
// Seleziona le righe corrispondenti in dt3
selezionare Righe corrispondenti ( dt3 , espr ( : ID ) , ID ) ;
,
// Cancella qualsiasi selezione esistente
dt2 << CancellaSeleziona ;
dt3 << CancellaSeleziona ;
) ;
) ;
// Assegna il gestore a dt1
rsh = dt1 << MakeRowStateHandler ( propagateSelectionToOtherTables ) ;
Ho trovato un modo molto più efficiente per affrontare il problema rispetto al mio approccio originale.
Per trasferire lo stato della riga (incluso e selezionato) di dtglobal in dt1, dt2, dt3 è possibile utilizzare quanto segue, funziona in modo rapido e dinamico anche per datatable di grandi dimensioni. Tutto ciò di cui hai bisogno è una colonna con una 'chiave' (valore numerico) corrispondente in ogni tabella.
//Trasferisce lo stato della riga di dtglobal ad altre tabelle
statehandler = dtglobal << Make Row State Handler ( statetransfer );
statetransfer = Funzione( {Y},
dt1 << cancella stati di riga;
dt2 << cancella stati di riga;
dt3 << cancella stati di riga;
excluderows = dtglobal << ottiene le righe escluse;
excludekeys = dtglobal:Key << ottieni valori;
excludekeys = excludekeys[excluderows];
dt1 < dt1 << escludi;
dt2 < dt2 << escludi;
dt3 < dt3 << escludi;
selectrows = dtglobal << ottiene le righe selezionate;
selectkeys = dtglobal:Key << ottieni valori;
selectkeys = selectkeys[selezionarighe];
dt1 < dt2 < dt3 < )
;
Grazie per la risposta PMroz.
Ho sperimentato qualcosa di simile a questo esempio: http://support.sas.com/demosdownloads/downarea_t4.jsp?productID=109646 .
Ho creato due tabelle di cui lo stato di inclusione/esclusione della tabella 2 dipende da quello della tabella 1 (in futuro questo potrebbe essere ampliato per includere anche gli altri stati come selezionato, visibile, colore ecc.).
Purtroppo il risultato non è ancora robusto. A volte funziona, ma dopo aver filtrato (includi/escludi) un paio di righe o fatto qualcos'altro, smette di funzionare. Sospetto che possa essere correlato a quale tabella di dati è corrente, ma non ne sono sicuro. L'uso dello script che ho scritto dalla finestra dello script (e non incorporato in table1) è leggermente più robusto ma a volte non riesce a fare nulla.
Qualsiasi pensiero su come migliorare ulteriormente questo approccio è molto apprezzato!
Basta eseguire lo script per le due tabelle nell'allegato per dare un'occhiata da soli. Lo script che utilizzo per collegare effettivamente le tabelle è anche in fondo all'allegato.
Breve sintesi:
Sia la tabella 1 che la tabella 2 hanno una colonna RepID.
Se una riga nella tabella 1 è inclusa/esclusa, la colonna :Excluded lo fa (per qualche motivo il riferimento dt/dt2 viene perso dopo aver avviato le tabelle, quindi lo definisco di nuovo qui):
Formula(
If( Escluso( Stato riga( Riga() ) ),
dt = tabella dati ("linktable1.jmp");
dt2 = Tabella dati ("linktable2.jmp");
Tabella dati corrente(dt);
1;
,
dt = tabella dati ("linktable1.jmp");
dt2 = Tabella dati ("linktable2.jmp");
Tabella dati corrente(dt);
0;
)
)
),
Quindi la colonna :parser fa questo:
If(:Excluded == 1, Eval(Parse(:ScriptEx)), :Excluded == 0, Eval(Parse(:ScriptInc)))
Che si riferisce a questo script (in :ScriptEx):
RepIDex = dt:RepID[];
Elenco di esclusione = Elenco();
Excludelist = As List(dt2 << Ottieni righe Where(dt2:RepID == RepIDex));
Tabella dati corrente(dt2);
Eval( For( i = 1, i <= N Items( Excludelist ), i++, Row State( Excludelist ) = Stato Escluso( 1 ) ) );
Vedi allegato per l'intero script inc. tavoli.