cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
The Discovery Summit 2025 Call for Content is open! Submit an abstract today to present at our premier analytics conference.
Choose Language Hide Translation Bar
View Original Published Thread

Expression Indexing: How to climb the Expression Tree?

hogi
Level XII

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:

  1. just works for a single level - flat hierarchy
  2. 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)
  3.  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]
1 ACCEPTED SOLUTION

Accepted Solutions
jthi
Super User

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

-Jarmo

View solution in original post

2 REPLIES 2
jthi
Super User

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

-Jarmo
hogi
Level XII


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!

hogi_0-1735977771997.png

 

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);