- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Expression Indexing: How to climb the Expression Tree?
This post was born as a wishlist entry - but it turns out that the wish is already partially possible (see @jthi's answer below).
So I moved it here to make the results more visible.
The original wish - which asks for a functionality which goes beyond what is already possible - can be found here:
Expression Indexing: read and write access
Please have a look and decide if it could help you as well ...
___________________________________________
In many programming languages, one can index lists and matrices. This is also possible in Jmp:
list= {"A", "B", "C"};
mat=[1,2,3];
list[3]
mat[2]
With Jmp 13, another level of indexing got possible: Data table subscripting
Nowadays the User can easily index entries in the data table with read and write access.
There is a third kind of indexing: Display Tree Indexing
For a given Report, you can walk down the Display Tree to identify a specific object:
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
gb = dt << Graph Builder(
Size( 437, 413 ),
Graph Spacing( 4 ),
Variables( X( :height ), Y( :weight ), Overlay( :sex ) ),
Elements( Points( X, Y, Legend( 1 ) ), Smoother( X, Y, Legend( 2 ) ) )
)
Report(gb)["Graph Builder"][AxisBox(1)]
Maybe there are more places in Jmp where indexing helps the user with his daily work ...
For Expressions it's much more complicated to walk down the tree:
To get the Y variable :weight from
myExpr=Expr(gb = dt << Graph Builder(
Size( 437, 413 ),
Graph Spacing( 4 ),
Variables( X( :height ), Y( :weight ), Overlay( :sex ) ),
Elements( Points( X, Y, Legend( 1 ) ), Smoother( X, Y, Legend( 2 ) ) )
));
one has to use
Arg(Arg(Arg(Arg(Arg(myExpr,2),2),3),2),1) // :weight
very fragile !!!!
A workaround: convert the Variables Expression into a list and use List-indexing:
myExpr=Expr(Variables( X( :height ), Y( :weight ), Overlay( :sex ) ))
Substitute(Name Expr(myExpr),Expr(Variables()),Expr(List()))["Y"];
but there are several disadvantages:
- just works for a single level - flat hierarchy
- just the first named argument is found, further named arguments with the same identifier are ignored:
myExpr=Expr(Variables( X( :height ), Y( :weight ),Y(:height ), Overlay( :sex ) )); Substitute(Name Expr(myExpr),Expr(Variables()),Expr(List()))["Y"]; // returns :weight, ignores Y(:height)
- just returns the first argument, further arguments get lost
myExpr = Expr(Distribution(columns(:height, :weight))); Substitute(Name Expr(myExpr),Expr(Distribution()),Expr(List()))["columns"]; //returns :height -> :weight gets lost
Is there a possibility, analogous to Display Tree Indexing, to climbing an Expression Tree?
instead of
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
myExpr=Expr(gb = dt << Graph Builder(
Size( 437, 413 ),
Graph Spacing( 4 ),
Variables( X( :height ), Y( :weight ), Y(:height), Overlay( :sex ) ),
Elements( Points( X, Y, Legend( 1 ) ), Smoother( X, Y, Legend( 2 ) ) )
));
//instead of:
Arg(Arg(Arg(Arg(Arg(myExpr,2),2),3),3),1)
I want to use
myExpr[2][2["Variables"]["Y"(2)][1]
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Expression Indexing: How to climb the Expression Tree?
There are some options on how you can do this already (but expression subscripting could be useful). Like I did mention in the wish list item (Expression Indexing: Help me climbing the Expression Tree - JMP User Community), JMP does have Extract Expr() which uses Wild() and Wild List()
Names Default To Here(1);
myExpr = Expr(
gb = dt << Graph Builder(
Size(437, 413),
Graph Spacing(4),
Variables(X(:height), Y(:weight), Overlay(:sex)),
Elements(Points(X, Y, Legend(1)), Smoother(X, Y, Legend(2)))
)
);
yexpr = Extract Expr(myExpr, Y(Wild()));
variables_expr = Extract Expr(myExpr, Variables(Wild List()));
Names Default To Here(1);
myExpr = Expr(
gb = dt << Graph Builder(
Size(437, 413),
Graph Spacing(4),
Variables(X(:height), Y(:weight), Y(:height), Overlay(:sex)),
Elements(Points(X, Y, Legend(1)), Smoother(X, Y, Legend(2)))
)
);
variables_expr = Extract Expr(myExpr, Variables(Wild List()));
idx = 0;
For(i = 1, i <= N Arg(variables_expr), i++,
firstlevel = Arg(variables_expr, i); // could use Extract Expr
If(Head(firstlevel) == Expr(Y) & idx == 2,
secondlevel = Arg(firstlevel, 1);
);
);
show(secondlevel);
There are also other things you can do (but not really sure if you should)
Names Default To Here(1);
myExpr = Expr(
Variables(X(:height), Y(:weight), Y(:height), Overlay(:sex))
);
listconversion = Substitute(Name Expr(myExpr), Expr(Variables()), Expr(List()));
yexprs = {};
While(yexpr = Contains(listconversion, Extract Expr(listconversion, Y(Wild()))),
Insert Into(yexprs, Remove From(listconversion, yexpr));
);
show(yexprs);
yexprs[2];
There could be other weird stuff you could do with lists...
Advanced Expressions, Macros, and Lists (jmp.com) can be a good read
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Expression Indexing: How to climb the Expression Tree?
There are some options on how you can do this already (but expression subscripting could be useful). Like I did mention in the wish list item (Expression Indexing: Help me climbing the Expression Tree - JMP User Community), JMP does have Extract Expr() which uses Wild() and Wild List()
Names Default To Here(1);
myExpr = Expr(
gb = dt << Graph Builder(
Size(437, 413),
Graph Spacing(4),
Variables(X(:height), Y(:weight), Overlay(:sex)),
Elements(Points(X, Y, Legend(1)), Smoother(X, Y, Legend(2)))
)
);
yexpr = Extract Expr(myExpr, Y(Wild()));
variables_expr = Extract Expr(myExpr, Variables(Wild List()));
Names Default To Here(1);
myExpr = Expr(
gb = dt << Graph Builder(
Size(437, 413),
Graph Spacing(4),
Variables(X(:height), Y(:weight), Y(:height), Overlay(:sex)),
Elements(Points(X, Y, Legend(1)), Smoother(X, Y, Legend(2)))
)
);
variables_expr = Extract Expr(myExpr, Variables(Wild List()));
idx = 0;
For(i = 1, i <= N Arg(variables_expr), i++,
firstlevel = Arg(variables_expr, i); // could use Extract Expr
If(Head(firstlevel) == Expr(Y) & idx == 2,
secondlevel = Arg(firstlevel, 1);
);
);
show(secondlevel);
There are also other things you can do (but not really sure if you should)
Names Default To Here(1);
myExpr = Expr(
Variables(X(:height), Y(:weight), Y(:height), Overlay(:sex))
);
listconversion = Substitute(Name Expr(myExpr), Expr(Variables()), Expr(List()));
yexprs = {};
While(yexpr = Contains(listconversion, Extract Expr(listconversion, Y(Wild()))),
Insert Into(yexprs, Remove From(listconversion, yexpr));
);
show(yexprs);
yexprs[2];
There could be other weird stuff you could do with lists...
Advanced Expressions, Macros, and Lists (jmp.com) can be a good read
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Expression Indexing: How to climb the Expression Tree?
Thanks, @jthi Extract Expr() is very helpful to get to the correct level of the tree.
It helped me a lot last year : )
I just noticed that the processing of arguments within one level can be done much easier:
For Each, Transform Each and Filter Each can be used with expressions. Cool!
Main Script = Expr(dt << Graph Builder(
Size( 437, 413 ),
Graph Spacing( 4 ),
Variables( X( :height ), Y( :weight ), Y (:sex), Overlay( :sex ) ),
Elements( Points( X, Y, Legend( 1 ) ), Smoother( X, Y, Legend( 2 ) ) )
));
snippet = Extract Expr(Main Script, Variables(Wild List()))
For each({variable}, Name Expr(snippet), Show(Head(variable), Arg(variable)))
selection = Filter Each ({code}, Name Expr(snippet), Head(code)==Expr(Y()));
Show(selection)
changed= Transform Each ({code}, Name Expr(snippet), If (Head(code)==Expr(X()), Expr(my changed code),Name Expr(code)))
Show(changed);