I 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(
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] )}}}
)
)
);
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?