반복적으로 수식을 포함하는 열 만들기를 해결하면서 이유를 이해할 수 없는 방식으로 솔루션을 구성해야 한다는 필요성을 발견했습니다. 내 초기 솔루션은
Names Default To Here( 1 );
dt =
// Open Data Table: semiconductor capability.jmp
// → Data Table( "semiconductor capability" )
Open( "$SAMPLE_DATA/semiconductor capability.jmp" );
colNames = dt << get column names( continuous, string );
For Each( {col}, colNames,
theTarget = (Column( Eval( col ) ) << get property( "Spec Limits" ))["Target"];
Eval(
Eval Expr(
New Column( col || " Minus Target",
Numeric,
"Continuous",
Format( "Best", 10 ),
Formula( As Column( Eval( col ) ) - Expr( theTarget ) )
)
)
);
);
그리고 그것은 실패합니다
Column NPN1 Minus Target Formula Interrupted
Name Unresolved: col at row 1 in access or evaluation of 'col' , col/*###*/
Formula evaluation errors have been ignored
Column NPN1 Minus Target Formula Interrupted
Name Unresolved: col at row 1001 in access or evaluation of 'col' , col/*###*/
Formula evaluation errors have been ignored
col 변수를 강제로 할당하면 코드가 작동합니다.
Names Default To Here( 1 );
dt =
// Open Data Table: semiconductor capability.jmp
// → Data Table( "semiconductor capability" )
Open( "$SAMPLE_DATA/semiconductor capability.jmp" );
colNames = dt << get column names( continuous, string )<BR /><BR />For Each( {xcol}, colNames,
col = xcol;
theTarget = (Column( Eval( col ) ) << get property( "Spec Limits" ))["Target"];
Eval(
Eval Expr(
New Column( col || " Minus Target",
Numeric,
"Continuous",
Format( "Best", 10 ),
Formula( As Column( Eval( col ) ) - Expr( theTarget ) )
)
)
);
);
또한 일단 코드를 실행하면
col = xcol;
xcol 할당 없이 코드를 실행할 수 있으며 원본 코드가 작동합니다.
이것은 나에게 혼란스럽다. 누구든지 이것의 이유를 설명할 수 있습니까?
아마도 JMP 직원이 정답을 제시해야 할 것입니다. @EvanMcCorkle ?
정확한 이유는 잘 모르겠지만 한 가지 이유는 열이 수식 내에서 평가되지 않는다는 것입니다( Eval()을 Expr()로 변경하여 As Column() 내부에 열 이름을 강제 적용)(또는 할 수 있다고 생각합니다) 실행 << 수식 생성 후 수식을 실행한 다음 수식을 즉시 제거하여 잘못된 열로 재평가되지 않도록 하세요.
col이 각 컨테이너 값에 대해 저장하는 변수인 경우 해당 값이 있는 루프 외부에는 존재하지 않습니다(xcol을 col로 설정하면 이를 우회함).
Names Default To Here(1);
a = {"a", "b", "c"};
b = "z";
show(b);
For Each({b}, a,
show(b);
);
show(b);
/*
b = "z";
b = "a";
b = "b";
b = "c";
b = "z";
*/
나는 이 방법(Expr(NameExpr(AsColumn()))을 사용하는 것을 선호합니다. 이렇게 하면 AsColumn("name") 대신 수식 "cleaner"(:name)가 남게 됩니다.
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/semiconductor capability.jmp");
colNames = (dt << get column names(continuous, string))[1::10];
For Each({col}, colNames,
theTarget = (Column(Eval(col)) << get property("Spec Limits"))["Target"];
Eval(
Eval Expr(
New Column(col || " Minus Target",
Numeric,
"Continuous",
Format("Best", 10),
Formula(Expr(NameExpr(As Column(col))) - Expr(theTarget))
)
)
);
);
이것은 다음과 같은 문제가 아닐 가능성이 높습니다. 각 루프에는 함수 로컬 범위가 있습니다. (이것은 매우 짜증나는 일입니다... 각 루프가 함수의 로컬 범위에서 제대로 작동하지 않습니다. 이 문제를 JMP 지원팀에 보고했습니다.)
Names Default To Here(1);
b = 2;
my_f = function({a}, {Default Local},
c = Transform Each({item}, a,
a * b
);
return(c);
);
my_f2 = function({a}, {Default Local},
b = b; // "Fix"
c = Transform Each({item}, a,
a * b
);
return(c);
);
Try(
show(my_f({1,2,3}));
,
show(exception_msg);
);
Try(
show(my_f2({1,2,3}));
,
show(exception_msg);
);