modo de sincronización?Hola a todos,
Estoy luchando con las partes asíncronas de JMP / JSL. Ahora entiendo que puede usar "Ejecutar fórmulas ()" para forzar la evaluación de una fórmula antes de usarla, pero tengo problemas similares con otras funciones:
Cuando se utiliza el valor, puede ser incorrecto. ¡Esto es muy peligroso!
¿Hay un "modo de sincronización forzada" en el que JSL va instrucción por instrucción y espera sistemáticamente que se complete uno antes de pasar al siguiente?
Ejemplo de mis problemas actuales, extraigo valores de una selección de filas (selRows) de una tabla (dt) para llenar una fila en otra tabla (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;¡Esto funciona a VECES! Pero a veces, todos los datos en la columna sumdt tienen el mismo valor y, a veces, no sale nada.
Sé que algunos recomiendan el comando de espera (0), pero leí a alguien diciendo que tampoco es una garantía.
Entonces, ¿cómo me aseguro de que los cálculos se completen?
¡Gracias!
Re: modo de sincronización?¡AAARGH!
Encontré el problema, era ... datos entrantes!
Pensé que algunas columnas en algunos archivos tienen un nombre idéntico al de los principales al principio, solo que con un dígito diferente (que elimino), PERO con un solo valor, ¡así que ahí van las estadísticas!
Mis más sinceras disculpas por el engaño! Todavía he aprendido sobre buenas prácticas, así que estoy agradecido.
¡Gracias a todos por el apoyo!
Re: modo de sincronización?Respondiendo a mi mismo:
No, no es la función estadística, es la forma en que obtengo los valores. El conjunto de números viene mal.
Re: modo de sincronización?Arreglé ambos, y no cambió mi problema.
Ya no creo que sea una condición de carrera. Es bastante sistemático y sucede en el mismo lugar en los mismos conjuntos de datos. Traté de barajar el orden de los artículos o reducir el alcance a un artículo por vez, poner el desarrollo de la pantalla como el primer cálculo, cambiar el orden de los elementos y aún tengo los mismos números exactos equivocados o faltantes en la salida.
¿Hay errores conocidos en 12.1 funciones estadísticas?
Re: modo de sincronización?- eliminar el tabla de datos actual (dt); y use un dt explícito donde sea necesario. la información actual de los datos puede cambiar si hace clic en una tabla mientras se está ejecutando la JSL.
- no use la columna [/ * corchetes vacíos sin subíndice * /] a menos que establezca una fila actual. El vacío [] significa "la fila actual". Los soportes vacíos por lo general no son necesarios. Su ejemplo probablemente necesita un subíndice de fila explícito.
Re: modo de sincronización?Hola de nuevo,
Gracias por su respuesta y perspicacia.
Desafortunadamente, todavía tengo los mismos problemas: valores faltantes, valores duplicados en el conjunto de salida (de Q10 a Media, falta StdDev).
Probé varias cosas. Hice un subíndice en el lateral para verificar algunos de los valores anormales "manualmente" y salieron bien.
Agregué muchas declaraciones de "espera".
¡Me he quedado sin ideas!
Aquí está el script (casi todo, se eliminó alguna verificación de la existencia de columnas, etc., es lo suficientemente 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();Re: modo de sincronización?En mi última respuesta utilicé una pequeña tabla que no necesariamente destacaría ningún problema de sincronización. Si hay un retraso será el cálculo de los cuantiles. El siguiente código calcula un cuantil para 10 millones de puntos de datos. La función se ejecuta de forma síncrona como cabría esperar, es decir, el programa no se ejecuta hasta que se haya establecido el valor de q. Si hubiera un problema de sincronización, veríamos que el valor de q se muestra como cero.
vals = J(10000000,1,Random Normal());
q = 0;
q = Quantile(0.5,vals);
show(q);
Sin embargo, como observación general, usaría Esperar (0) si quisiera asegurar la sincronización, esto normalmente solo se relaciona con problemas de tipo de E / S. Solo hay casos raros en los que la espera no funciona, y eso se debe a que la ejecución se ejecuta en un subproceso separado.
Re: modo de sincronización?Es mucho más fácil de diagnosticar si puede proporcionar algún código de ejemplo que podamos ejecutar y que replique el problema. Sin eso he escrito mi propia versión. Contiene todo su código, pero he proporcionado la fuente de la tabla y el destino (sumdt). La única diferencia es que tiene la notación thisCol [] que implica que está utilizando un bucle For Each Row. No entendí el contexto de eso, así que simplemente usé un bucle 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;
);
Este código funciona bien sin problemas de sincronización. Es posible que desee comparar el código y ver qué es diferente.
Re: modo de sincronización?Podrías intentar usar un bucle. Podría incorporar un paso en el bucle que copia el valor a una matriz o una matriz asociativa antes de que comience el siguiente bucle. Eso probablemente haría que las cosas sigan la cadencia que deseas.
Mejor,
METRO