JSL を使用した実行時データ テーブル式の構築私は時々この問題に遭遇しますが、満足のいく解決策を思いついていないので、他の人はどのようなことをしたのか知りたいと思っています。列名と追加の数式の値は実行時までわからないものとします。簡単な例として、ユーザーが指定した値で列を乗算する数式を作成するとします。
これは機能しません:
buildFormula = Function({tblRef,colName,mult},
exprOut = Substitute(
Expr(col*mult),
Expr(col),Column(tblRef,colName),
Expr(mult),mult
);
Name Expr(exprOut);
);
outExpr = buildFormula(tbl,"Minimum Price ($1000)",3);
Eval(Substitute(
Expr(tbl << New Column("New Formula Column",Formula(form))),
Expr(form),Name Expr(outExpr)
));
以下も同様です:
tbl = Open("$sample_data/cars 1993.JMP");
buildFormula = Function({colRef,mult},
exprOut = Substitute(
Expr(col*mult),
Expr(col),colRef,
Expr(mult),mult
);
Name Expr(exprOut);
);
outExpr = buildFormula(Column(tbl,"Minimum Price ($1000)"),Name Expr(fExpr));
Eval(Substitute(
Expr(tbl << New Column("New Formula Column",Formula(form))),
Expr(form),Name Expr(outExpr)
));
数式を入力すると(評価をクリックするまでは)機能しているように見えますが、何か見落としているのでしょうか?私はこのアプローチを使っています
tbl = Open("$sample_data/cars 1993.JMP");
buildFormula = Function({colRef,mult},
exprOut = Substitute(
Expr(col[Row()]*mult),
Expr(col),colRef,
Expr(mult),mult
);
Name Expr(exprOut);
);
outExpr = buildFormula(Column(tbl,"Minimum Price ($1000)"),3);
Eval(Substitute(
Expr(tbl << New Column("New Formula Column",Formula(form))),
Expr(form),Name Expr(outExpr)
));
しかし、数式を正しく評価するために行()を使用するのは好ましくありません。最初の 2 つのスクリプトの動作はバグでしょうか?
Re: JSL を使用したランタイム データ テーブル式の構築このようなものは機能しますか? row() 関数を使用しませんが、まさにあなたがしようとしている方法ではこれを実現できません。私はこのページからそれを盗みました (eval/expr タイプの作業を行う必要があるときはいつでもブックマークしています)。
tbl = Open( "$sample_data/cars 1993.JMP" );
buildFormula = Function( {colRef, mult},
Eval(
Eval Expr(
tbl << New Column( "New Formula Column", Formula( as column (expr (colRef)) * expr (num(mult)) ) )
)
)
);
outExpr = buildFormula( Column( tbl, "Minimum Price ($1000)" ), 3 );Re: JSL を使用したランタイム データ テーブル式の構築ありがとう、ジェド。
これは、リンクと同様に役に立ちます。問題の説明をもっと明確にすべきでした。数式の評価は関数の一部にすることはできません。数式表現をコードの他の部分で使用する予定なので、すぐに評価したくありません。
Re: JSL を使用したランタイム データ テーブル式の構築以下は、Chris のために私が書いたコードの抜粋です。他の数式から数式を作成し、それがプロファイラーをサポートしていることを確認する必要があります。参照に空の添え字を使用すると役立ちましたが、別の問題が発生しました。何をしたいのかはわかりませんが、このスニペットが役立つアイデアを提供してくれることを願っています。
For( r = 1, r <= nResponses, r++,
// convert a column reference to a column name for substitution
Col Ref to Name = Function( {colref, qualified? = 0 },
If( qualified?,
Parse(Eval Insert("^colref << Get Data Table^:\!"^colref << Get Name^\!"n")),
Parse(Eval Insert(":\!"^colref << Get Name^\!"n"))
)
);
// create expected improvement column formula
limits = Column( dt, y col[r] ) << Get Property( "Response Limits" );
goal[r] = Char( limits["Goal"] );
Match( goal[r],
"Maximize", // apply standard EI formula
Eval(
Substitute(
Expr(
ei = dt << New Column( y col[r] || " Expected Improvement", "Numeric", "Continuous",
Formula(
(:pppfff - yyy) * Normal Distribution( (:pppfff - yyy) / Sqrt( :vvvfff ))
+ Sqrt( :vvvfff ) * Normal Density( (:pppfff - yyy) / Sqrt( :vvvfff ) )
)
)
),
Expr( vvvfff ), Col Ref To Name(vf),
Expr( pppfff ), Col Ref To Name(pf),
Expr( yyy ), refY[r] = predOptY[r]
)
),
"Minimize", // negate standard EI formula
Eval(
Substitute(
Expr(
ei = dt << New Column( y col[r] || " Expected Improvement", "Numeric", "Continuous",
Formula(
(yyy - :pppfff) * Normal Distribution( (yyy - :pppfff) / Sqrt( :vvvfff ))
+ Sqrt( :vvvfff ) * Normal Density( (yyy - :pppfff) / Sqrt( :vvvfff ) )
) )
),
Expr( vvvfff ), Col Ref To Name(vf),
Expr( pppfff ), Col Ref To Name(pf),
Expr( yyy ), refY[r] = predOptY[r]
)
),
"Match Target", // apply joint EI formula
Eval(
Substitute(
Expr(
ei = dt << New Column( y col[r] || " Expected Improvement", "Numeric", "Continuous",
Formula(
deltaMin = Abs( ttt - yyy );
deltaMin * (Normal Distribution( (deltaMin + ttt - :pppfff) / Sqrt( :vvvfff ) )
- Normal Distribution( (-deltaMin + ttt - :pppfff) / Sqrt( :vvvfff ) )
)
+ Sqrt( :vvvfff ) * (
Normal Density( (deltaMin + ttt - :pppfff) / Sqrt( :vvvfff ) )
+ Normal Density( (-deltaMin + ttt - :pppfff) / Sqrt( :vvvfff ) )
- 2 * Normal Density( ttt - :pppfff) / Sqrt( :vvvfff )
)
- (:pppfff - ttt) * (
(Normal Distribution( (deltaMin + ttt - :pppfff)) / Sqrt( :vvvfff ) )
+ Normal Distribution( (-deltaMin + ttt - :pppfff) / Sqrt( :vvvfff ) )
- 2 * Normal Distribution( (ttt - :pppfff) / Sqrt( :vvvfff ) )
)
)
)
),
Expr( vvvfff ), Col Ref To Name(vf),
Expr( pppfff ), Col Ref To Name(pf),
Expr( ttt ),
target[r] = If( Contains( Char( limits ), "Middle" ),
limits["Middle"],
(limits["Lower"] + limits["Upper"]) / 2
),
Expr( yyy ),
/*
yDiff = (Column( dt, y col ) << Get as Matrix) - target[r];
pDiff = (pf << Get As Matrix) - target[r];
refY[r] = If( Min( Abs( yDiff ) ) < Min( Abs( pDiff ) ),
Column( dt, y col )[Loc Min( Abs( yDiff ) )],
pf[Loc Min( Abs( pDiff ) )]
)
*/
predOptY[r]
)
),
"None", // unexpected condition
Throw( "Disallowed: response with Goal of None" ),
// unexpected condition
gp << Close Window;
dt << Delete Columns( { pf, vf } );
Throw( "Disallowed: No response goal found. Response Limits column property is missing" )
);
ei << Set Property( "Response Limits", {Goal( Maximize ), Importance( 1 ), Show Limits( 0 )} )
<< Hide( 1 );
Wait( 0 );
Eval(
Substitute(
Expr(
Insert Into( utilityCols, eee, iii );
),
Expr( eee ), Eval( ei ),
Expr( iii ), 3*(r-1) + 1
)
);
);Re: JSL を使用したランタイム データ テーブル式の構築私も Mark と同じような方法をとったようです。数式を文字列として構築し、列に適用する準備ができたら、 insert() と eval( parse() ) を eval することができます。これはあなたのスクリプトでも機能しますか?
tbl = Open("$sample_data/cars 1993.JMP");
colName = "Minimum Price ($1000)";
mult = 3;
formulaString = ":\!"^colName^\!"n * ^mult^";
formula = eval insert( formulaString );
newColumnString = "^tbl^ << new column( \!"New Formula\!", formula( ^formula^ ) )";
newColumn = eval insert( newColumnString );
eval( parse( newColumn ) );Re: JSL を使用したランタイム データ テーブル式の構築数年前、 @ジョセフ・モーガンとこの件について話していたとき、彼は文字列の連結や置換の使用を強く勧めず、式の処理ですべてを実現できるが、1 つの例外があるだけであり、その例外はもう問題ではないかもしれないと示唆していました。文字列を使用すると、コードの読み取りと保守がはるかに難しくなります。おそらく他にももっと根本的な理由があるのでしょうが、思い出せません。
結局のところ、 スコープとして()関数を使用した簡単な解決策があります ( ブレイディに感謝)
</CODE></PRE>
<PRE><CODE class=" language-jsl">tbl = Open("$sample_data/cars 1993.JMP");
buildFormula = Function({colRef,mult},
exprOut = Substitute(
Expr(col*mult),
Expr(col),Name Expr(As Scoped(colRef)),
Expr(mult),mult
);
Name Expr(exprOut);
);
outExpr = buildFormula(Column(tbl,"Minimum Price ($1000)"),3);
Eval(Substitute(
Expr(tbl << New Column("New Formula Column",Formula(form))),
Expr(form),Name Expr(outExpr)
));<BR />