cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Choose Language Hide Translation Bar
hogi
Level XI

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 list and matrices. This is also possible in Jmp:

 

list= {"A", "B", "C"};
mat=[1,2,3];
list[3]
mat[2]

 

From 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 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 in 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 to 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?

 

something like: 

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] //assign // send // Graph Builder // Variables

 

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

1 REPLY 1
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