グラフビルダーにおける動的な列割り当てのためのJSLスクリプトJMPのグラフビルダーを使用してグラフを生成するセッションスクリプトを作成しようとしています。しかし、データが更新される時期によってデータの列数が変化するため、グラフビルダーのスクリプトを更新のたびに手動で修正する必要があり、問題が発生しています。
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.
このアプローチをJSL(JMPスクリプト言語)でどのように実装できるかを知りたいのですが、私自身は効果的なスクリプトを作成できていません。未完成のJSLドラフトをお持ちとのことでしたが、質問には含まれていませんでした。もしドラフトをご提供いただければ、修正のお手伝いや解決策のご提案をさせていただきます。
私も以下のエラーに遭遇しています。→[For Each 、Bad Argument( colName )、For Each/*###*/(colName, columnNames,...引数はリストである必要があります。 ]
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
)
);
自動化とスクリプト作成Re: グラフビルダーにおける動的な列割り当てのためのJSLスクリプト列タグを使って列を「グループ化」することを検討しましたか?
これは同様の機能を提供することができ、さらに重複する「グループ」も許可します。
例えばこんな感じです。
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) ));
ちなみに、これは各({col}、cols、body)ごとに適用されます。
Re: グラフビルダーにおける動的な列割り当てのためのJSLスクリプト
ホギさん、お返事ありがとうございます。
列タグのことは考えていませんでした。もう一度列タグを使ってスクリプトを修正してみます。
それが終わってから返信します。
Re: グラフビルダーにおける動的な列割り当てのためのJSLスクリプト使用状況に応じて、既に提案されているようなタグ、カスタム列プロパティ、プレフィックス付き列名、列グループなどを使用できます。どのオプションにもそれぞれ長所と短所があります。
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);
それと…これはコミュニティの質問とLLMの課題を組み合わせたようなものでしょうか(コミュニティに参加している私たちは人間ですから、きっとそうですよね)?
Re: JSL scripting for dynamic column asignment in graph builder日本語の返答ですが、お許しください(こちらの方が本意が伝わるかと思いまして)。
JMP learnBotに質問しても解決できなかった事例について、この度、コミュニティの皆様にも共有させていただいております。
やはり、知見をお持ちの方々のスクリプトの記述方法やアドバイスをいただくことで、私自身のスクリプト技術の向上を図り、さらには身近なJMPユーザーのスキルアップにも貢献したいと考え、このコミュニティを利用させていただいております。
しかしながら、いつもご丁寧にご回答くださるjthiさんのお気持ちを害してしまったのではないかと案じており、大変申し訳なく思っております。もし、質問の仕方において不躾な点や改善すべき点がございましたら、今後のためにぜひご指摘いただけますと幸いです。
Re: グラフビルダーにおける動的な列割り当てのためのJSLスクリプトあなたの投稿に腹を立てたわけではありませんが、まるで促されているように感じて、少し違和感を覚えました。もし促し文を使ったのであれば、それを分けて投稿することをお勧めします。
LearnBotはJSLの扱いにはあまり向いていません。なぜなら、JSLでの入力を求められていないからです。Assistantの方が少しはマシかもしれませんが、LLM(例えばClaudeなど、できれば会社が利用できるもの)に指示を与えて、何をすべきか(JSL)を理解させた方が、より良い結果が得られるかもしれません。
Re: JSL scripting for dynamic column asignment in graph builderJthiさんのおっしゃる通りで私の中でLLMへのプロンプトとJMPユーザーコミュニティへの投稿の間に明確な区別ができていませんでした。
今後、LLMへの質問なのか、JMPユーザーコミュニティへの投稿として適切なのか、内容をより精査します。円滑なコミュニケーションのために意識すべき重要な点にご指摘いただき、ありがとうございます。
これからもどうぞよろしくお願いいたします。
Re: グラフビルダーにおける動的な列割り当てのためのJSLスクリプトスクリプト自体を動作させる方法をお探しの場合は、以下の更新版が参考になるかもしれません。変更した箇所にはコメントを付けていますが、最も複雑な部分は、Eval( Eval Insert( ) ) 関数を使用して、列のリストをローカルデータフィルタに挿入する部分です。このためのさまざまなオプションについては、「Eval Insert、Eval Expr、Parse、Substitute を使用して、ある式を別の式に挿入する」を参照してください。
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
)
)
));
Re: グラフビルダーにおける動的な列割り当てのためのJSLスクリプトJSL初心者です。もし以前に同じ質問と回答があったらご容赦ください。
私がやりたいことは、上記のグラフビルダースクリプトを修正して、PNP列の色を使用してIVP列とNPN列をプロットすることです。修正したスクリプト(Multiple Column Switcher.jsl)を添付します。このスクリプトには3つの列スイッチャーが含まれています。また、必要なIVP、NPN、PNP列の組み合わせを手動で選択する必要があります。IVP、NPN、PNP列がすべて1対1でマッピングされていることがわかっている場合(たとえば、IVP3とNPN3およびPNP3)、単一の列スイッチャーでそれを行うにはどうすればよいでしょうか?
Re: グラフビルダーにおける動的な列割り当てのためのJSLスクリプト私はディスカバリーサミットでの私のヒントとコツのプレゼンテーション(「 スキップ、ホップ、そしてJMPを1分で:スーパーユーザーからのJMPの知恵を凝縮した一口サイズ版(2026-EU-30MP-2767)」、ヒント「誰でも使える列切り替えツール(複数列切り替えツール)」)で、これの簡略版を紹介しました。
これは非常に簡単な方法です(ただし、NPNは他のものよりも列数が多いため、その場合は誤った列が使用されることに注意してください)。
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();
スタックデータテーブルとローカルデータフィルタも、このような場合に良い選択肢となる可能性があります。