Find and extract an expression argument with a given expression headI want to write an efficient script that will take as an input a JSL expression and:
- Find an argument in that expression that has a specific expression head
- Substitute that argument with a modified version of that argument
Example:
I have this expression
my_expr=Expr(<BR />Fit Model(
Y( :y ),
Effects( :Drug, :x ),
Personality( "Standard Least Squares" ),
Emphasis( "Effect Leverage" ),
Run(
:y << {Summary of Fit( 1 ), Analysis of Variance( 1 ),
Parameter Estimates( 1 ), Scaled Estimates( 0 ),
Plot Actual by Predicted( 1 ), Plot Residual by Predicted( 1 ),
Plot Studentized Residuals( 0 ), Plot Effect Leverage( 1 ),
Plot Residual by Normal Quantiles( 0 ), Box Cox Y Transformation( 0 ),
{:Drug << {LSMeans Contrast( [1 0 -1] )}}}
)
)<BR />);I want to find the "LSMeans Contrast(...)" argument that is buried in the expression and extract that expression in to a new expression, let's call that extracted_expression.
So in this case I want
extracted_expression = Expr(LS Means Contrast([1 0 -1]))
I then want to get the argument to that expression, modify it, and then modify the extracted_expression, and substitute the modified argument expression for the original extracted expression. . For example:
new_expression=Substitute(Name Expr(extracted_expression), arg(extracted_expression,1), [-1 0 .5]);
Substitute(Name Expr(my_expr), Name Expr(extracted_expression), Name Expr(new_expression));
The resulting expression would be
Fit Model(
Y( :y ),
Effects( :Drug, :x ),
Personality( "Standard Least Squares" ),
Emphasis( "Effect Leverage" ),
Run(
:y << {Summary of Fit( 1 ), Analysis of Variance( 1 ),
Parameter Estimates( 1 ), Scaled Estimates( 0 ),
Plot Actual by Predicted( 1 ), Plot Residual by Predicted( 1 ),
Plot Studentized Residuals( 0 ), Plot Effect Leverage( 1 ),
Plot Residual by Normal Quantiles( 0 ), Box Cox Y Transformation( 0 ),
{:Drug << {LS Means Contrast( [-1 0 0.5] )}}}
)
)
Where I am getting stuck is step 1, how to traverse the arguments of the original expression to find the argument that has an an expression with the specified header (in this example, the head of the argument is LS Means Contrast).
Any suggestions/ideas on how to do this?
Automation and ScriptingRe: Find and extract an expression argument with a given expression headNote, this isn't the real problem I'm working on, the expression provided above is just an example that has an expression argument buried deep in an expression.
Re: Find and extract an expression argument with a given expression headExtract Expr()does the magic : )

Re: Find and extract an expression argument with a given expression headExtract Expr maybe what you are looking for?
Names Default To Here(1);
my_expr=Expr(Fit Model(
Y( :y ),
Effects( :Drug, :x ),
Personality( "Standard Least Squares" ),
Emphasis( "Effect Leverage" ),
Run(
:y << {Summary of Fit( 1 ), Analysis of Variance( 1 ),
Parameter Estimates( 1 ), Scaled Estimates( 0 ),
Plot Actual by Predicted( 1 ), Plot Residual by Predicted( 1 ),
Plot Studentized Residuals( 0 ), Plot Effect Leverage( 1 ),
Plot Residual by Normal Quantiles( 0 ), Box Cox Y Transformation( 0 ),
{:Drug << {LSMeans Contrast( [1 0 -1] )}}}
)
));
myhead = Extract Expr(my_expr, LSMeans Contrast(Wild()));
myarg = Arg(part, 1);
//show(myhead, myarg);
new_expr = Substitute(Name Expr(myhead), myarg, [1 0 1]);
my_expr2 = Substitute(Name Expr(my_expr), Name Expr(myhead), Name Expr(new_expr));
Show(my_expr, my_expr2);
Re: Find and extract an expression argument with a given expression headHere are some details /pitfalls of extract expr():
Extract Expr
Re: Find and extract an expression argument with a given expression headimportant to know:
extract expr() is not greedy , it will stop after finding the first match.
On the other hand, Substitute() IS greedy.
The 2-step Substitute in @jthi 's code is essential!
my_expr=Expr(Fit Model(
{:Drug << {LSMeans Contrast( [1 0 -1] )}}
);
[1 0 -1] // another time the same Arg, lives in danger
);
part= Extract Expr(my_expr, LSMeans Contrast(Wild()));
myarg = Arg(part, 1); //part instead of myhead
new_expr = Substitute(Name Expr(myhead), myarg, [1 0 1]);
my_expr2 = Substitute(Name Expr(my_expr), Name Expr(myhead), Name Expr(new_expr));<BR /><BR />// won't work<BR />// my_expr3 = Substitute(Name Expr(my_expr), Name Expr(myarg), [1 0 1]);Here, the issue is obvious - but there are other cases where it is more difficult to control which expression gets substituted.
related wishes:
Substitute First Occurrence
:folded_hands: Expression Indexing: read and write access
subst() - substitute() 2.0
Re: Find and extract an expression argument with a given expression headThanks @jthi and @hogi . I wasn't familiar with Extract Expr() and the Wild() expression. Works nicely for what I am actually working on. Much appreciated.