数式を含む列を反復的に作成する問題を解く際に、なぜか理解できない方法でソリューションを構成する必要があることに気付きました。私の最初の解決策は
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 ?
正確な理由はわかりませんが、1 つの理由は、列が数式内で評価されないことです ( Eval() を Expr() に変更して、列名を As Column() 内に強制します) (または、数式の作成後に << run formulas を実行し、その後すぐに数式を削除して、間違った列で再評価されないようにすることもできます)。
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") ではなく、: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);
);