그래프 빌더에서 동적 열 할당을 위한 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
)
);
자동화 및 스크립팅제목: 그래프 빌더에서 동적 열 할당을 위한 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)에 대한 것 입니다.
제목: 그래프 빌더에서 동적 열 할당을 위한 JSL 스크립팅 관련
답변해주셔서 감사합니다, 호기님.
컬럼 태그를 고려하지 못했네요. 컬럼 태그를 사용해서 스크립트를 다시 수정해 보겠습니다.
그렇게 한 후에 답장드리겠습니다.
제목: 그래프 빌더에서 동적 열 할당을 위한 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 과제가 혼합된 형태인가요? (커뮤니티에 있는 우리는 모두 사람이니까요.)
제목: 그래프 빌더에서 동적 열 할당을 위한 JSL 스크립팅 관련일본어의 답변입니다만, 용서해 주세요(이쪽이 본의가 전해질까라고 생각해).
JMP learnBot에 질문해도 해결할 수 없었던 사례에 대해서, 이번에, 커뮤니티의 여러분에게도 공유하고 있습니다.
역시, 지견을 가지고 계신 분들의 스크립트의 기술 방법이나 어드바이스를 받음으로써, 나 자신의 스크립트 기술의 향상을 도모해, 나아가서는 친숙한 JMP 유저의 스킬 업에도 공헌하고 싶다고 생각해, 이 커뮤니티를 이용하겠습니다.
그러나, 언제나 정중하게 대답해 주시는 jthi씨의 기분을 해해 버린 것이 아닐까라고 생각하고 있어, 대단히 죄송하게 생각하고 있습니다. 만약, 질문의 방법에 있어서 부적절한 점이나 개선해야 할 점이 있으면, 향후를 위해서 꼭 지적해 주시면 감사하겠습니다.
제목: 그래프 빌더에서 동적 열 할당을 위한 JSL 스크립팅 관련당신의 게시글에 기분이 상한 건 아니지만, 마치 누군가 우리에게 특정 질문을 하도록 유도하는 듯한 느낌이 들어서 좀 불편했습니다. 만약 유도 문구를 사용하셨다면, 그 부분을 따로 분리하시는 게 좋겠습니다.
LearnBot은 JSL 프롬프트 방식이 아니기 때문에 JSL 처리 능력이 그다지 좋지 않습니다. Assistant는 조금 더 나을 수도 있지만, LLM(예: Claude, 가급적 회사에서 사용 가능한 버전)에 프롬프트를 보내 JSL을 입력하도록 하면 더 나은 결과를 얻을 수 있습니다.
제목: 그래프 빌더에서 동적 열 할당을 위한 JSL 스크립팅 관련Jthi 씨가 말씀하신대로 내가 LLM에 대한 프롬프트와 JMP 사용자 커뮤니티에 게시하는 것 사이에 명확한 구별이 없었습니다.
앞으로 LLM에 대한 질문인지, JMP 사용자 커뮤니티에 대한 게시물로 적절한지, 내용을 좀 더 검토해 보겠습니다. 원활한 커뮤니케이션을 위해 의식해야 할 중요한 점을 지적해 주셔서 감사합니다.
앞으로도 잘 부탁드립니다.
제목: 그래프 빌더에서 동적 열 할당을 위한 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
)
)
));
제목: 그래프 빌더에서 동적 열 할당을 위한 JSL 스크립팅 관련저는 JSL 초보자라서, 혹시 이전에 이미 질문되고 답변된 내용이라면 양해 부탁드립니다.
제가 원하는 것은 위의 그래프 빌더 스크립트를 수정하여 IVP 열과 NPN 열을 PNP 열의 색상으로 표시하고 싶습니다. 수정된 스크립트(Multiple Column Switcher.jsl)는 3개의 열 전환기를 포함하고 있습니다. 현재 스크립트에서는 IVP, NPN, PNP 열의 조합을 수동으로 선택해야 합니다. 만약 IVP, NPN, PNP 열이 모두 1:1로 매핑되어 있다면(예: IVP3 대 NPN3 및 PNP3), 단일 열 전환기로 원하는 조합을 만들 수 있는 방법이 있을까요?
제목: 그래프 빌더에서 동적 열 할당을 위한 JSL 스크립팅 관련저는 디스커버리 서밋에서 진행한 팁&트릭 프레젠테이션( Skip, Hop, and JMP a Minute: 슈퍼 유저가 알려주는 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();
이와 같은 경우에는 스택형 데이터 테이블과 로컬 데이터 필터도 좋은 선택이 될 수 있습니다.