modalità di sincronizzazione?Ciao a tutti,
Sto lottando con le parti asincrone di JMP / JSL. Ora capisco che puoi usare "Esegui formule ()" per forzare la valutazione di una formula prima di usarla, ma ho problemi simili con altre funzioni:
Quando si utilizza il valore, potrebbe essere errato. Questo è molto pericoloso!
Esiste una "modalità di sincronizzazione forzata" in cui il JSL passa all'istruzione con istruzioni e attende sistematicamente che uno sia completato prima di passare al successivo?
Esempio dei miei problemi attuali, estrai i valori da una selezione di righe (selRows) da una tabella (dt) per riempire una riga in un'altra tabella (sumdt):
thisCol = Column(sumdt, thisName||"_Q10");
valueSet = Column(dt, colList[i])[selRows];
thisValue = Quantile(0.10, valueSet);
thisCol[] = thisValue;
thisCol = Column(sumdt, thisName||"_Q25");
thisValue = Quantile (0.25, valueSet);
thisCol[] = thisValue;
thisCol = Column(sumdt, thisName||"_Q50");
thisValue = Quantile (0.50, valueSet);
thisCol[] = thisValue;
thisCol = Column(sumdt, thisName||"_Q75");
thisValue = Quantile (0.75, valueSet);
thisCol[] = thisValue;
thisCol = Column(sumdt, thisName||"_Q90");
thisValue = Quantile (0.90, valueSet);
thisCol[] = thisValue;Questo funziona A VOLTE! Ma a volte, tutti i dati nella colonna sumdt hanno lo stesso valore e, a volte, nulla viene fuori.
Conosco qualche consiglio e il comando wait (0), ma leggo qualcuno dicendo che non è nemmeno una garanzia.
Quindi, come posso assicurarmi che i calcoli vengano completati ??
Grazie!
Ri: modalità di sincronizzazione?AAARGH!
Ho trovato il problema, è stato ... dati in arrivo!
Ho immaginato che alcune colonne su alcuni file avessero un nome identico a quelli principali all'inizio, solo con una cifra diversa (che spoglio), MA con un solo valore, quindi ci sono le statistiche!
Le mie profonde scuse per l'ingannevole! Ho ancora imparato a conoscere le buone pratiche, quindi per quello sono grato.
Grazie a tutti per il supporto!
Ri: modalità di sincronizzazione?Rispondendo a me stesso:
No, non è la funzione statistica, è il modo in cui recupero i valori. L'insieme di numeri è sbagliato.
Ri: modalità di sincronizzazione?Ho risolto entrambi e non ha cambiato il mio problema.
Non credo più che sia una condizione di gara. È abbastanza sistematico e accade nello stesso posto sullo stesso insieme di dati. Ho cercato di mescolare l'ordine degli articoli o di ridurre l'ambito a un elemento alla volta, mettere lo stddv come primo calcolo, modificare l'ordine degli elementi e ho ancora gli stessi numeri esatti errati o mancanti nell'output.
Ci sono dei bug noti sulle funzioni statistiche 12.1?
Ri: modalità di sincronizzazione?- Rimuovi il tabella dati corrente (dt); e utilizzare un dt esplicito dove necessario. il dato dati corrente può cambiare se si fa clic su una tabella mentre il JSL è in esecuzione.
- non utilizzare la colonna [/ * parentesi vuote senza indice * /] a meno che non si imposti una riga corrente. Il vuoto [] significa "la riga corrente". Le parentesi vuote di solito non sono necessarie. Il tuo esempio probabilmente ha bisogno di un indice di riga esplicito.
Ri: modalità di sincronizzazione?Ciao di nuovo,
Grazie per la tua risposta e intuizione.
Sfortunatamente, ho ancora gli stessi problemi: valori mancanti, valori duplicati in set di output (da Q10 a Mean, StdDev mancante).
Ho provato più cose. Ho fatto un pedice sul lato per controllare alcuni dei valori anormali "manualmente" e sono usciti bene.
Ho aggiunto molte dichiarazioni di "attesa".
Sono piuttosto fuori dalle idee!
Ecco lo script (quasi tutto, rimosso alcune verifiche per l'esistenza di colonne, ecc., È abbastanza grande):
Names Default To Here(1);
dt = Current Data Table();
colNames = dt << Get Column Names (String);
Summarize(itemsList = by("Item"));
binsList = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D"};
colNamesSum = sumdt << Get Column Names (String);
For (k=1, k <= Nitems(itemsList), k++,
itemID = itemsList[k];
dt << Select All Rows << Exclude(0);
dt << Select Where (dt:Item == itemID);
itemRows = dt << Get Selected Rows;
prodID = Right(Column (dt, "proc_id")[itemRows[1]],4);
lotID = Regex(Column(dt, "lot_id")[itemRows[1]], "\d{6}");
show(lotID,itemID);
checkDup = sumdt << Get Rows Where (:Lot == lotID & :Item == itemID);
If(NRows(checkDup) == 0,
newIt = 1;
show(newIt);
sumdt << AddRows(1);
Column(sumdt, "Test Date")[] = Column(dt, "finish_t")[itemRows[1]];
Column(sumdt, "Item")[] = itemID;
Column(sumdt, "N ")[] = NRow(itemRows);
Column(sumdt, "Product")[] = prodId;
Column(sumdt, "Lot")[] = lotID;
dt << Invert Row Selection << Exclude(1);
Current Data Table(dt);
Summarize(bins = by(:SBIN_NUM), countTable = count());
dt << Select All Rows << Exclude(0);
Current Data Table(sumdt);
For (i=1, i <= Nitems(binsList), i++,
binPos = Contains(bins, binsList[i]);
Column(sumdt, "Bin"||binsList[i])[] =
If(binPos == 0, 0, countTable[binPos]);
);
colNamesSum = sumdt << Get Column Names (String);
For (i=1, i<= Nitems(colList), i++,
thisName = colNames[colList[i]];
show(thisName);
valueSet = Column(dt, colList[i])[itemRows];
thisValueQ10 = Quantile(0.10, valueSet);
wait(0);
thisValueQ25 = Quantile (0.25, valueSet);
wait(0);
thisValueQ50 = Quantile (0.50, valueSet);
wait(0);
thisValueQ75 = Quantile (0.75, valueSet);
wait(0);
thisValueQ90 = Quantile (0.90, valueSet);
wait(0);
thisValueMean = Mean (valueSet);
wait(0);
thisValueStdDev = Std Dev (valueSet);
wait(0);
show(thisValueStdDev);
thisColQ10 = Column(sumdt, thisName||"_Q10");
thisColQ25 = Column(sumdt, thisName||"_Q25");
thisColQ50 = Column(sumdt, thisName||"_Q50");
thisColQ75 = Column(sumdt, thisName||"_Q75");
thisColQ90 = Column(sumdt, thisName||"_Q90");
thisColMean = Column(sumdt, thisName||"_Mean");
thisColStdDev = Column(sumdt, thisName||"_StdDev");
thisColQ10[] = thisValueQ10;
thisColQ25[] = thisValueQ25;
thisColQ50[] = thisValueQ50;
thisColQ75[] = thisValueQ75;
thisColQ90[] = thisValueQ90;
thisColMean[] = thisValueMean;
thisColStdDev[] = thisValueStdDev;
);
show("Item completed"),
newIt = 0;
show(newIt);
show("Item already exists in summary table!");
New Window("WARNING",
<< modal,
Text Box("Item "||lotId||"-"||itemID||" already in the table"),
Text Box("Skipping this item"),
Button Box("OK")
);
);
);
show("Lot completed");
sumdt << Save();Ri: modalità di sincronizzazione?Nella mia ultima risposta ho usato una piccola tabella che non necessariamente evidenziava i problemi di sincronizzazione. Se c'è un ritardo sarà il calcolo dei quantili. Il codice sottostante calcola un quantile per 10 milioni di punti dati. La funzione viene eseguita in modo sincrono come ci si aspetterebbe, ovvero lo spettacolo non viene eseguito fino a quando non viene stabilito il valore di q. Se ci fosse un problema di sincronizzazione, vedremmo il valore di q essere mostrato come zero.
vals = J(10000000,1,Random Normal());
q = 0;
q = Quantile(0.5,vals);
show(q);
Come osservazione generale, userei Wait (0) se volessi garantire la sincronizzazione, che normalmente si riferisce solo ai problemi di tipo I / O. Ci sono solo rari casi in cui Wait non funziona - e questo perché l'esecuzione è in esecuzione in un thread separato.
Ri: modalità di sincronizzazione?È molto più facile diagnosticare se è possibile fornire un codice di esempio che è possibile eseguire per replicare il problema. Senza di ciò ho scritto la mia versione. Contiene tutto il codice ma ho fornito la tabella sorgente e destinazione (sumdt). L'unica differenza è che hai la notazione thisCol [] che implica che stai usando un ciclo For Each Row. Non ho capito il contesto di questo, quindi ho semplicemente usato un ciclo For:
dt = Open("$SAMPLE_DATA/Big Class.jmp");
colList = dt << Get Column Names(string,numeric);
N = NItems(colList);
sumdt = new table("sumdt",
Add Rows(N),
new column("name", character),
new column("Q10"),
new column("Q25"),
new column("Q50"),
new column("Q75"),
new column("Q90"),
);
selRows = dt << Get Rows Where(:sex=="F");
For (i=1,i<=N,i++,
thisName = colList[i];
Column(sumdt,"name")[i] = thisName;
thisCol = Column(sumdt, "Q10");
valueSet = Column(dt, colList[i])[selRows];
thisValue = Quantile(0.10, valueSet);
thisCol[i] = thisValue;
thisCol = Column(sumdt, "Q25");
thisValue = Quantile (0.25, valueSet);
thisCol[i] = thisValue;
thisCol = Column(sumdt, "Q50");
thisValue = Quantile (0.50, valueSet);
thisCol[i] = thisValue;
thisCol = Column(sumdt, "Q75");
thisValue = Quantile (0.75, valueSet);
thisCol[i] = thisValue;
thisCol = Column(sumdt, "Q90");
thisValue = Quantile (0.90, valueSet);
thisCol[i] = thisValue;
);
Questo codice funziona correttamente senza problemi di sincronizzazione. Potresti voler confrontare il codice e vedere cosa è diverso.
Ri: modalità di sincronizzazione?Potresti provare ad usare un ciclo. È possibile incorporare un passaggio nel ciclo che copia il valore in una matrice o in una matrice associativa prima dell'avvio del ciclo successivo. Questo probabilmente farebbe in modo che le cose seguano la cadenza che desideri.
Migliore,
M