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)
));
하지만 Row()를 사용하여 수식을 제대로 평가해야 하는 건 싫습니다. 처음 두 스크립트의 동작은 버그인가요?
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을 사용한 런타임 데이터 테이블 수식 빌드크리스를 위해 쓴 코드의 일부 발췌문입니다. 다른 수식에서 수식을 빌드하고 프로파일러를 지원하는지 확인해야 합니다. 참조에 빈 아래 첨자를 사용하면 도움이 되었지만 다른 문제가 발생했습니다. 무엇을 하려는지 잘 모르겠지만 이 스니펫이 사용할 수 있는 좋은 아이디어를 제공하기를 바랍니다.
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와 비슷한 경로를 택한 것 같습니다. 수식을 문자열로 구성한 다음 열에 적용할 준비가 되면 eval insert() 및 eval(parse())을 실행할 수 있습니다. 이것이 스크립트에 적용 가능할까요?
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을 사용한 런타임 데이터 테이블 수식 빌드몇 년 전 @조셉 모건 과 이런 종류의 것에 대해 이야기할 때, 그는 문자열 연결이나 대체 사용을 강력히 반대했고, 모든 것이 표현식 처리를 통해 달성될 수 있다고 말했는데, 내가 기억하지 못하고 더 이상 문제가 되지 않을 수 있는 한 가지 예외가 있습니다. 문자열을 사용하면 코드를 읽고 유지하기가 훨씬 더 어려워집니다. 아마도 다른 더 근본적인 이유가 있겠지만 기억이 나지 않습니다.
결과적으로 Scoped()로 지정됨 함수를 사용하면 간단한 솔루션이 있습니다( @브래디_브래디 에게 감사드립니다)
</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 />