도움말, 스크립트가 스크립트 창에서는 제대로 실행되지만 열 수식에서 실행하면 실패합니다.안녕하세요,
저는 M개의 요인이 N개의 측정항목에 미치는 개별적인 통계적 영향을 분석하여 데이터 표를 요약하는 스크립트를 만들었습니다.
요약 표는 M개의 요인(열)이 있는 N개의 측정 항목(행)의 행렬을 보여줍니다. 여기에는 평균 이동, Cpk 저하 또는 둘 다라는 특정 영향이 있습니다.
선택한 각 행에 대한 분포를 열 수식을 사용하여 그리는 기능을 추가하고 싶습니다.
나는 이 게시물에서 영감을 얻었습니다:
(JMP 테이블의) 셀을 스크립트에 연결하나요?
문제는 내 스크립트가 고정된 선택된 행(이 예에서는 [5])이 있는 새 스크립트 창에서 잘 작동하지만 :Graph 열 수식에 스크립트를 포함하면 실패한다는 것입니다. 왜 그런지 이해가 안 갑니다...
디버깅을 도와주실 수 있나요?
첨부된 2개의 테이블: 원시 데이터가 있는 datatable_test.jmp, 열 수식이 있는 Summary.jmp. 아이디어는 :Graph 열에서 플롯하려는 셀을 클릭하는 것입니다.
현재 오류는 다음과 같습니다: "행 [ ]에서 불법 참조(재귀)가 있습니다."

두 테이블을 모두 연 상태에서 다음 스크립트를 실행하면 예상대로 작동합니다(아래 참조). 하지만 테이블에서 직접 실행하면 스크립트가 실패합니다(그래프 열의 셀을 클릭).

미리 감사드립니다.
- 설교자
// this script works from a Script window
// All features related to the column formula are commented
// here the row selected is row 5 : rn1 = [5]
Names Default To Here( 1 );
dt = Data Table( "datatable_test" );
dt2 = Data Table( "Summary" );
//If( Selected( Row State() ),
Eval(
Parse(
rn1 = [5]/*dt2 << get selected rows*/;
rn = rn1[1];
Factors = dt2 << get column names( "string" );
show(rn1, rn);
Eval(
Eval Expr(
For( i = N Items( Factors ), i >= 1, i--,
CurrCol = Column( dt2, Factors[i] );
If(Char( CurrCol[ rn ] ) == "Ok" | Factors[i] == "Metric"| Factors[i] == "Graph",
Remove From( Factors, i, 1 )
);
)
)
);
FactorA = "X( :" || Char( Factors[1] ) || ", Position( 1 ))";
FactorB = "X(1)";
For( j = 2, j <= N Items( Factors ), j++,
FactorA = Char( FactorA ) || ",X( :" || Char( Factors[j] ) ||
", Position( 1 ))";
FactorB = Char( FactorB ) || ",X( " || Char( j ) || " ) ";
);
Show( dt2:Metric[rn], FactorA, FactorB );
Key = dt2:Metric[rn];
Eval Insert(
" dt << Graph Builder(
Size( 534, 464 ),
Show Control Panel( 0 ),
Show Legend( 0 ),
Variables(
Y( ^Key^ ), ^FactorA^),
Elements( Box Plot( Y, Legend( 18 ), ^FactorB^ ) ),
SendToReport(
Dispatch(
{},
ScaleBox,
{Min( -0.485125992718803 ), Max( 5.53364268893602 ), Inc( 1 ),
Minor Ticks( 0 )}
)
)
) "
);
)
//)
);자동화 및 스크립팅Re: 도움말, 스크립트 창에서는 스크립트가 제대로 실행되지만 열 수식에서 실행하면 실패합니다.열 수식으로 이 작업을 하는 데 특별한 이유가 있습니까? 예를 들어 테이블 상자와 버튼이 있는 사용자 지정 창을 만드는 것이 빌드하고 관리하기가 훨씬 쉬울 것입니다. 또는 요약 테이블에 행 상태 핸들러를 사용하는 것(가능하다면 피하겠지만).
Re: 도움말, 스크립트 창에서는 스크립트가 제대로 실행되지만 열 수식에서 실행하면 실패합니다.안녕하세요 Jarmo님,
특별한 이유는 없고, 데이터 테이블을 사용해 요약을 생성한 방식으로 원래 스크립트를 만들었을 뿐입니다.
저는 그걸 생각해내지 못했습니다. 테이블 상자를 열고 버튼을 추가하는 게 좋은 생각인 듯합니다. 그 점을 염두에 두고 나중 버전을 수정할 수도 있을 것 같습니다.
하지만 그동안 열 수식을 작동하게 하는 것이 가치가 있다고 생각하세요? 그러면 다음 버전 전에 더 빨리 작동하는 버전을 가질 수 있겠죠? 데이터 테이블 대신 테이블 상자를 생성하도록 구조를 변경하는 데 시간이 좀 걸릴 것 같아요. 아직 디스플레이/테이블 상자에 익숙하지 않거든요.
열 수식에 포함하려는 스크립트 조각은 자체적으로 작동하지만 열 수식에서 실행하면 실패합니다. 뭔가 잘못한 것 같지만 무엇인지 잘 모르겠습니다...
Re: 도움말, 스크립트 창에서는 스크립트가 제대로 실행되지만 열 수식에서 실행하면 실패합니다.편집하다:
실제로 테이블을 디스플레이 상자로 변환하는 것이 쉽다는 것을 알게 되었습니다.
nw = New Window("Report",
dt << Get As Report()
);아래에 보고서가 생성되었습니다

보고서에서 행을 클릭했을 때 수식이 작동할 것이라고는 예상하지 못했습니다(실제로 작동하지 않았습니다...).
하지만 지금은 귀하의 제안을 어떻게 진행해야 할지 잘 모르겠습니다.
(다시 말하지만 저는 아직 디스플레이 상자 조작에 익숙하지 않습니다)
미리 감사드립니다
Re: 도움말, 스크립트 창에서는 스크립트가 제대로 실행되지만 열 수식에서 실행하면 실패합니다.편집 2:
나는 마침내 Jarmo의 추천과 이 게시물에 따라 스크립트를 작동시켰습니다.
JSL 도움말: 보고서 및 테이블 상자로 가져오기
이제 보고서에서 행을 클릭하면 선택한 행에 따라 스크립트가 실행됩니다. 이는 바로 내가 필요로 했던 것입니다.:)

아래 스크립트는 내가 첫 번째 메시지에서 조인한 2개의 테이블을 열어야 합니다.
감사해요
- 설교자
Names Default To Here( 1 );
dt7 = Data Table("Summary");
dt = Data Table("datatable_test");
dt7 << clear select;
dt7 << Clear Column Selection();
RptWin = New Window( "Data Table as report",
Outline Box("Data Table as Report",
dt7_Rpt = dt7 << Get as Report();
)
);
tb = dt7_Rpt[Table Box( 1 )];
tb << Set Heading Column Borders( 1 );
tb << Set Selectable Rows( 1 );
tb << Set Row Change Function(
Function( {this},
{SelRows},
SelRows = this << Get Selected Rows;
If(
N Items( SelRows ) > 1, Throw( "Too many items selected!\!rOnly one selection possible." ),
N Items( SelRows ) == 1,
SelRows = this << Get Selected Rows;
);
dt7 << Clear Select;
rn = dt7 << Select rows( SelRows ) << get selected rows;
show (rn[1], dt7:Metric[rn]);
Factors = dt7 << get column names( "string" );
Eval(
Eval Expr(
For( i = N Items( Factors ), i >= 1, i--,
CurrCol = Column( dt7, Factors[i] );
If(Char( CurrCol[ rn[1] ] ) == "Ok" | Factors[i] == "Metric"| Factors[i] == "Graph",
Remove From( Factors, i, 1 )
);
)
)
);
show (Factors);
Try(FactorA = "X( :" || Char( Factors[1] ) || ", Position( 1 ))");
FactorB = "X(1)";
For( j = 2, j <= N Items( Factors ), j++,
Try(FactorA = Char( FactorA ) || ",X( :" || Char( Factors[j] ) || ", Position( 1 ))");
FactorB = Char( FactorB ) || ",X( " || Char( j ) || " ) ";
);
Show( dt7:Metric[rn], FactorA, FactorB );
Key = dt7:Metric[rn];
If (Factors != {},
Eval(Parse(Eval Insert(
" dt << Graph Builder(
Size( 534, 464 ),
Show Control Panel( 0 ),
Show Legend( 0 ),
Variables(Y( ^Key^ ), ^FactorA^),
Elements(
Box Plot( Y, Legend( 18 ), ^FactorB^ ),
Caption Box(X, Y, Legend(20), Summary Statistic( \!"N\!" ),Location( \!"Graph per factor\!" ))),
SendToReport(
Dispatch(
{},
ScaleBox,
{Min( -0.485125992718803 ), Max( 5.53364268893602 ), Inc( 1 ),
Minor Ticks( 0 )}
)
)
) "
))),
Eval(Parse(Eval Insert(
" dt << Graph Builder(
Size( 534, 464 ),
Show Control Panel( 0 ),
Show Legend( 0 ),
Variables(Y( ^Key^ )),
Elements(
Box Plot( Y, Legend( 18 )),
Caption Box(Y, Legend(20), Summary Statistic( \!"N\!" ))),
SendToReport(
Dispatch(
{},
ScaleBox,
{Min( -7.06199976676385 ), Max( 26.8097086791615 ), Inc( 5 ),
Minor Ticks( 0 )}
)
)
) "
)))
)
));Re: 도움말, 스크립트 창에서는 스크립트가 제대로 실행되지만 열 수식에서 실행하면 실패합니다.제가 시도할 또 다른 개선점은 Eval(Parse())를 없애는 것입니다(보통 스크립트를 디버깅하기 쉽게 만들고 나쁜 습관을 배우지 않습니다). 하지만 약간의 노력과 다양한 기술이 필요하므로 천천히 작업할 수 있습니다.
약 12시간 후에 살펴보도록 하겠습니다. 그러면 잠재적으로 무엇을 할 수 있는지 아이디어를 얻을 수 있습니다.
Re: 도움말, 스크립트 창에서는 스크립트가 제대로 실행되지만 열 수식에서 실행하면 실패합니다.동의합니다. 한 걸음 더 나아가 Eval Insert() 도 교체하겠습니다.
Eval(Parse()) 에 관해서는 건너뛸 수 있습니다.

Parse는 문자열을 인수로 기대합니다.
표현식이 평가되고 결과 문자열이 구문 분석되어 표현식으로 반환됩니다.
Parse(Print(1);"a"||"b")
그래서,
Parse(Print(1);Eval Insert(Graph Builder());"a")
1을 인쇄하고 그래프를 만들고 표현식으로 a를 반환합니다. 중앙 부분에만 관심이 있다면 Parse를 건너뛸 수 있습니다.
Parse(Eval Insert())를 Eval() 로 래핑해도 여전히 평가됩니다.
반면, Eval(Eval Expr())은 내부에 있는 Expr() 을 평가하는 데만 필요합니다.
Expr()이 없으면 코드에서 제거해도 문제가 없습니다.
일반적으로, 저는 도움말/샘플 데이터 폴더의 데이터 세트를 기반으로 하는 코드를 게시하는 것을 제안합니다.
그러면 인터넷을 통해 파일을 다운로드할 필요 없이 바로 코드를 실행할 수 있습니다.
추가적인 이점은 다양한 입력에 맞게 코드를 조정하면 문제를 이해하는 데 도움이 된다는 것입니다.
질문을 게시할 적절한 코드가 있을 때면 종종 질문이 사라지곤 합니다 : )

Re: 도움말, 스크립트 창에서는 스크립트가 제대로 실행되지만 열 수식에서 실행하면 실패합니다.이것은 복잡해 보이지만(실제로도 그렇습니다) 제가 가장 많이 접근하는 방식은 다음과 같습니다(유일한 방법은 아니며 << 변수 추가/<< 요소 추가를 활용할 수도 있습니다)
Names Default To Here(1);
dt_summary = Open("$DOWNLOADS/Summary.jmp");
dt = Open("$DOWNLOADS/datatable_test.jmp");
dt << New Column("Ones", Numeric, Nominal, Set Each Value(1));
dt_summary << clear select;
dt_summary << Clear Column Selection();
possible_factors = dt_summary << get column names("string");
Remove From(possible_factors, Contains(possible_factors, "Metric"));
Remove From(possible_factors, Contains(possible_factors, "Graph"));
create_report = function({sel_row}, {Default Local},
valid_factor_idx = Loc(dt_summary[sel_row, possible_factors], "Ok");
valid_factors = possible_factors[valid_factor_idx];
key = dt_summary[sel_row, "Metric"];
If(N Items(valid_factors) == 0,
valid_factors = {"Ones"};
);
variables_expr = Expr(Variables());
bp_expr = Expr(Box Plot(Y, Legend(18)));
dt = dt; // JMP being JMP
For Each({valid_factor, idx}, valid_factors,
x_expr = EvalExpr(X(Expr(Name Expr(AsColumn(dt, valid_factor))), Position(1)));
Insert Into(variables_expr, Name Expr(x_expr));
Insert Into(bp_expr, Eval Expr(X(Expr(idx))));
);
y_expr = EvalExpr(Y(Expr(Name Expr(AsColumn(dt, key)))));
Insert Into(variables_expr, Name Expr(y_expr));
gb_expr = Substitute(
Expr(dt << Graph Builder(
Size(534, 464),
Show Control Panel(0),
Show Legend(0),
_variables_,
Elements(
_boxplot_,
Caption Box(X, Y, Legend(20), Summary Statistic("N"), Location("Graph per factor"))
),
SendToReport(
Dispatch({}, ScaleBox, {Min(-7.06199976676385), Max(26.8097086791615), Inc(5), Minor Ticks(0)})
)
)),
Expr(_variables_), Name Expr(variables_expr),
Expr(_boxplot_), Name Expr(bp_expr)
);
gb = Eval(gb_expr);
return();
);
nw = New Window("Data Table as report",
Outline Box("Data Table as Report",
summary_report = dt_summary << Get as Report();
)
);
report_tb = summary_report[Table Box(1)];
report_tb << Set Heading Column Borders(1);
report_tb << Set Selectable Rows(1);
report_tb << Set Row Change Function(Function({this},
selrows = this << Get Selected Rows;
If(N Items(selrows) > 1,
Throw("Too many items selected!\!rOnly one selection possible.")
);
create_report(selrows[1]);
));
Write();
이것이 작동한 후에는 사용자 경험에 대해 생각해 볼 수 있을 것 같습니다.
- 선택한 행을 누르면 해당 행에 대한 보고서가 생성되는 버튼을 사용해야 할까요?
- 사용자가 두 개 이상의 행을 선택할 수 있도록 할 수 있나요?
- 이 경우 모든 보고서를 같은 창에 만들어야 합니까?
- 그래프가 이미 생성된 경우 다시 만들어야 합니까?
- 사용자가 창을 닫으면 데이터 테이블도 닫아야 합니까?
- ..
더 보기...Names Default To Here(1);
dt_summary = Open("$DOWNLOADS/Summary.jmp");
dt = Open("$DOWNLOADS/datatable_test.jmp");
dt << New Column("Ones", Numeric, Nominal, Set Each Value(1));
dt_summary << clear select;
dt_summary << Clear Column Selection();
possible_factors = dt_summary << get column names("string");
Remove From(possible_factors, Contains(possible_factors, "Metric"));
Remove From(possible_factors, Contains(possible_factors, "Graph"));
create_report = function({sel_row}, {Default Local},
valid_factor_idx = Loc(dt_summary[sel_row, possible_factors], "Ok");
valid_factors = possible_factors[valid_factor_idx];
key = dt_summary[sel_row, "Metric"];
If(N Items(valid_factors) == 0,
valid_factors = {"Ones"};
);
variables_expr = Expr(Variables());
bp_expr = Expr(Box Plot(Y, Legend(18)));
dt = dt; // JMP being JMP
For Each({valid_factor, idx}, valid_factors,
x_expr = EvalExpr(X(Expr(Name Expr(AsColumn(dt, valid_factor))), Position(1)));
Insert Into(variables_expr, Name Expr(x_expr));
Insert Into(bp_expr, Eval Expr(X(Expr(idx))));
);
y_expr = EvalExpr(Y(Expr(Name Expr(AsColumn(dt, key)))));
Insert Into(variables_expr, Name Expr(y_expr));
gb_expr = Substitute(
Expr(dt << Graph Builder(
Size(534, 464),
Show Control Panel(0),
Show Legend(0),
_variables_,
Elements(
_boxplot_,
Caption Box(X, Y, Legend(20), Summary Statistic("N"), Location("Graph per factor"))
),
SendToReport(
Dispatch({}, ScaleBox, {Min(-7.06199976676385), Max(26.8097086791615), Inc(5), Minor Ticks(0)})
)
)),
Expr(_variables_), Name Expr(variables_expr),
Expr(_boxplot_), Name Expr(bp_expr)
);
return(gb_expr);
);
nw = New Window("Data Table as report",
H List Box(
Outline Box("Data Table as Report",
summary_report = dt_summary << Get as Report();
),
Outline Box("Actions",
Button Box("Create Reports",
sel_rows = report_tb << Get Selected Rows;
lub_collector = Lineup Box(N Col(2));
For Each({selrow}, sel_rows,
lub_collector << Append(create_report(selrow));
);
nw_graphs = New Window("Graphs",
lub_collector
);
wait(0);
),
Button Box("Close Window", summary_report << close window);
)
)
);
report_tb = summary_report[Table Box(1)];
report_tb << Set Heading Column Borders(1);
report_tb << Set Selectable Rows(1);
I will edit and add images here if JMP Community ever lets me do it...
Edit: Images


Re: 도움말, 스크립트 창에서는 스크립트가 제대로 실행되지만 열 수식에서 실행하면 실패합니다.Jarmo와 Hogi에게 정말 감사드려요.
제가 매우 늦게 답변드립니다. 답변이 늦어져서 죄송합니다. 지난 몇 달 동안 다른 우선순위에 집중해야 했지만, 이제 다시 이 일에 집중할 수 있게 되었습니다!
이에 대해 생각해 보고 귀하의 제안을 시도해 볼게요.
최상의,
-설교자