回复:表达式索引:如何爬表达式树?已经有一些关于如何执行此操作的选项(但表达式下标可能很有用)。 就像我在愿望清单项目中提到的那样(表达式索引:帮助我爬上表达式树 - JMP 用户社区),JMP 确实有 Extract Expr(),它使用 Wild() 和 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);
您还可以做其他事情(但不确定是否应该这样做)
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];
你还可以用列表做其他奇怪的事情......
高级表达式、宏和列表 (jmp.com)可以很好地阅读
表达式索引:如何爬表达式树?这篇文章诞生于一个愿望清单 - 但事实证明这个愿望已经部分实现(见下面@jthi的回答)。
所以我将其移到这里以使结果更加明显。
最初的愿望 - 要求实现超出现有能力的功能 - 可以在这里找到:
表达式索引:读写访问
请查看并决定它是否也能帮助您...
___________________________________________
在许多编程语言中,可以索引列表和矩阵。在 Jmp 中也可以这样做:
list= {"A", "B", "C"};
mat=[1,2,3];
list[3]
mat[2]
使用 Jmp 13,可以实现另一级别的索引: 数据表下标
现在,用户可以轻松地以读写权限索引数据表中的条目。
还有第三种索引:显示树索引
对于给定的报告,您可以沿着显示树来识别特定对象:
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)]
也许 Jmp 中还有更多地方可以通过索引来帮助用户完成日常工作......
对于表达式来说,沿着树走下去要复杂得多:
获取 Y 变量:weight来自
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 ) ) )
));
必须使用
Arg(Arg(Arg(Arg(Arg(myExpr,2),2),3),2),1) // :weight
非常脆弱!!!!
解决方法:将变量表达式转换为列表并使用列表索引:
myExpr=Expr(Variables( X( :height ), Y( :weight ), Overlay( :sex ) ))
Substitute(Name Expr(myExpr),Expr(Variables()),Expr(List()))["Y"];
但也有几个缺点:
- 仅适用于单层级 - 扁平层级
- 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
是否有可能,类似于显示树索引,攀爬表达树?
而不是
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)
我想使用
myExpr[2][2["Variables"]["Y"(2)][1]
自动化和脚本回复:表达式索引:如何爬上表达式树?谢谢, @jthi Extract Expr()对于到达树的正确级别非常有帮助。
去年它帮了我很多忙:)
我刚刚注意到,在一个级别内处理参数可以变得更容易:
For Each 、 Transform Each和Filter Each可以与表达式一起使用。太酷了!

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