同期モード?こんにちは、みんな、
JMP / JSLの非同期部分に苦労しています。今、私はあなたがそれを使用する前に式の評価を強制するために "Run Formulas()"を使用することができることを理解しています、しかし私は他の関数に関して同様の問題を抱えています:
値が使用されると、正しくない可能性があります。これはとても危険です。
JSLが命令ごとに進み、次へ進む前に1つが完了するのを体系的に待つ「強制同期モード」がありますか?
現在の問題の例として、あるテーブル(dt)から選択した行(selRows)から値を抽出し、別のテーブル(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;これはいくつかうまくいきます!しかし、sumdt列のすべてのデータがまったく同じ値になっていることがあり、まったく何も出てこないこともあります。
wait(0)コマンドをお勧めしますが、それは保証ではないという人もいます。
それでは、計算が確実に完了するようにするにはどうすればよいですか。
ありがとうございます。
再:同期モード?AAARGH!
私は問題を見つけた、それは… 着信データ
私はいくつかのファイルのいくつかのカラムは最初のメインのものと同じ名前を持っていて、違う数字(私はそれを取り除きます)を持っていますが、ただ一つの値だけで、統計があります!
誤解を招くことを深くお詫び申し上げます。私はいまだに良い習慣について学んできたので、そのために感謝します。
ご支援ありがとうございました!
再:同期モード?自分に答える:
いいえ、それは統計関数ではありません、それは私が値を取得する方法です。数字の集合が間違っています。
再:同期モード?私は両方とも直しました、そしてそれは私の問題を変えませんでした。
私はもはやそれが競合状態だとは思わない。それはかなり体系的で同じデータセットの同じ場所で起こっています。私は、アイテムの順序を入れ替えたり、スコープを一度に1つのアイテムに縮小したり、最初の計算としてstd devを配置したり、要素の順序を変更したりしました。
12.1統計関数に関する既知のバグはありますか?
再:同期モード?- を削除現在のデータテーブル(dt)。必要に応じて明示的なdtを使用してください。JSLの実行中にテーブルをクリックすると、現在のデータデータテーブルが変わる可能性があります。
- 現在の行を設定しない限り、カラム[/ *空の角括弧なしの* /]は使用しないでください。空の[]は「現在の行」を意味します。空の括弧は通常必要ありません。あなたの例はおそらく明示的な行の添え字が必要です。
再:同期モード?また会ったね、
あなたの答えと洞察力をありがとう。
残念ながら、私はまだ同じ問題を抱えています:欠損値、出力セット内の重複した値(Q10からMean、StdDev欠損)。
私は複数のことを試しました。私は側に添字を付けて、「手動で」いくつかの異常値をチェックしましたが、それらはうまく出ました。
たくさんの "wait"ステートメントを追加しました。
私は全くアイデアがない!
これがスクリプトです(ほとんどすべてのもの、列の存在などの検証を削除しました。十分な大きさです)。
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();再:同期モード?前回の回答では、同期の問題を浮き彫りにしない小さなテーブルを使用しました。 遅れがある場合は分位数の計算になります。 以下のコードは、1000万データポイントの分位点を計算します。 あなたが予想するように、関数は同期的に動きます、すなわち、ショーはqの値が確立されるまで実行されません。 同期の問題がある場合は、qの値がゼロとして表示されます。
vals = J(10000000,1,Random Normal());
q = 0;
q = Quantile(0.5,vals);
show(q);
ただし、一般的な観察として、同期を確実にしたい場合はWait(0)を使用します。これは通常、入出力タイプの問題にのみ関係します。Waitが機能しない場合は稀ですが、それは実行が別のスレッドで実行されているためです。
再:同期モード?問題を再現するために実行できるサンプルコードを提供できれば、診断がはるかに簡単になります。 それなしで私は私自身のバージョンを書いた。 それはあなたのすべてのコードを含んでいますが、私はテーブルのsourceとdestinationを提供しました(sumdt)。 唯一の違いは、thisCol []という表記があることです。これは、For Each Rowループを使用していることを意味します。 その文脈がわからなかったので、単純に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;
);
このコードは、同期の問題がなくても正常に機能します。 コードを比較して、何が違うのかを確認することをお勧めします。
再:同期モード?あなたはループを使ってみることができます。次のループが始まる前に、値を行列または連想配列にコピーするステップをループに組み込むことができます。それはおそらくあなたが望む調子に物事を追従させるでしょう。
ベスト、
M