使用 Eval Insert、Eval Expr、Parse 和 Substitute 将一个表达式插入另一个表达式问题您需要插入变量的值变成一个表达式而不评估整个代码。示例包括:
- 使用脚本编写列公式
- 使用另一个脚本编写脚本
下面是一个用于转换表中选定列的脚本。 这确实不是有效,因为表达式“cols[i]”保存在列公式中,而不是列名称中。
//Open A Table and select a few columns
dt = Open( "$Sample_data/iris.jmp" );
cols = {Sepal length, Petal length};
//This code does not work
For( i = 1, i <= N Items(cols), i++,
dt << New Column(
"2 * " || Char( cols[i] ),
Numeric,
"Continuous",
Formula( As Column( cols[i] ) * 2)
)
);
使用正确的名称创建新列,但公式如下:

解决方案
有两种通用策略可以解决此问题:构建表达式,同时在其余部分之前评估其中的一部分;以及将表达式构建为字符串,然后评估它。 请注意,插入的变量实际上可以是任意长度的表达式。
表达式
这些方法涉及编写表达式并在其余部分之前评估其中的一部分。 找到 Eval、Eval Expr 和 Expr 的正确组合可能很棘手,但您可以看到语法突出显示并使用脚本编辑器来确保括号匹配。
评估,评估表达式
编写表达式并包装应使用 Expr() 立即计算的任何部分:
//Eval Expr
For( i = 1, i <= N Items(cols), i++,
Eval( Eval Expr(
dt << New Column(
"2 * " || Char( cols[i] ),
Numeric,
"Continuous",
Formula( As Column( Expr( Char( cols[i] ) ) ) * 2)
)
) )
);
代替
编写表达式并用计算代码替换其中的一部分:
//Substitute
For( i = 1, i <= N Items(cols), i++,
Eval( Substitute(
Expr( dt << New Column(
"2 * " || cn,
Numeric,
"Continuous",
Formula( As Column( cn ) * 2)
) ),
Expr( cn ),
Char( cols[i] )
) )
);
字符串方法
这些方法涉及将表达式编写为字符串,使用 Parse() 将其转换为表达式,然后使用 Eval() 对其进行实际评估。 这些方法的缺点包括看不到任何语法突出显示,需要使用 \!" 或 \[ ... ]\ 处理双引号,并且将来通常很难排除故障或修改,尤其是对于长表达式。
评估插入物
将表达式编写为字符串,并使用“内联”代码进行计算并将其放置在字符串内,然后解析并计算它:
//Eval Insert
For( i = 1, i <= N Items(cols), i++,
Eval( Parse( Eval Insert(
"\[dt << New Column(
"2 * ^Char( cols[i] )^",
Numeric,
"Continuous",
Formula( As Column( "^Char( cols[i] )^" ) * 2)
)]\"
) ) );
);
代替
将表达式写入带有占位符的字符串中,该占位符将替换为计算的表达式。 请注意,这与上面的函数相同:
//Substitute
For( i = 1, i <= N Items(cols), i++,
Eval( Parse( Substitute(
"\[dt << New Column(
"2 * ColumnName",
Numeric,
"Continuous",
Formula( As Column( "ColumnName" ) * 2)
)]\",
"ColumnName",
Char( cols[i] )
) ) );
);
连接
最基本的形式,使用“||”编写表达式。请注意,您可以使用 \[ ... ]\ 而不是 \!":
//Concatenate
For( i = 1, i <= N Items(cols), i++,
Eval( Parse(
"dt << New Column(
\!"2 * " || Char( cols[i] ) || "\!",
Numeric,
\!"Continuous\!",
Formula( As Column( \!"" || Char( cols[i] ) || "\!" ) * 2)
)"
) );
);
也可以看看
将变量或表达式插入到其他表达式中。这是对 Eval()、Eval Expr()、Substitute()、Parse() 和 Eval Insert() 的简要介绍。
回复:使用 Eval Insert、Eval Expr、Parse 和 Substitute 将一个表达式插入另一个表达式以下是表达式方法和字符串方法的示例:
Names default to here(1);
//Open A Table and select a few columns
dt = Open( "$Sample_data/iris.jmp" );
cols = {Sepal length, Petal length};
//Eval Expr
For( i = 1, i <= N Items(cols), i++,
Eval( Eval Expr(
dt << New Column(
"Eval Expr 2 * " || Char( cols[i] ),
Numeric,
"Continuous",
Formula( Expr( cols[i] ) * 2 )
)
) )
);
//Substitute with String
For( i = 1, i <= N Items(cols), i++,
Eval( Parse( Substitute(
"\[dt << New Column(
"Substitute String 2 * ColumnName",
Numeric,
"Continuous",
Formula( :"ColumnName"n * 2)
)]\",
"ColumnName",
Char( cols[i] )
) ) );
);
回复:使用 Eval Insert、Eval Expr、Parse 和 Substitute 将一个表达式插入另一个表达式这可能有一些不必要的功能,但您可以将 Name Expr 与列引用一起使用(As Column(name)):
Names Default To Here(1);
//Open A Table and select a few columns
dt = Open("$Sample_data/iris.jmp");
cols = {Sepal length, Petal length};
For(i = 1, i <= N Items(cols), i++,
Eval(Eval Expr(dt << New Column("2 * " || Char(cols[i]), Numeric, "Continuous", Formula(Expr(Name Expr(As Column(Char(cols[i])))) * 2))))
);
回复:使用 Eval Insert、Eval Expr、Parse 和 Substitute 将一个表达式插入另一个表达式有没有一种方法不需要 As Column() ?
在这里,我们需要在传递字符串时包含它,我想知道如何做到这一点,以便公式保留 :column。
回复:使用 Eval Insert、Eval Expr、Parse 和 Substitute 将一个表达式插入另一个表达式多谢! 是的。 你对循环的开始是对的。 我没有意识到这一点。
回复:使用 Eval Insert、Eval Expr、Parse 和 Substitute 将一个表达式插入另一个表达式@新手,
for 循环从 i=2 开始,这就是它跳过第一列的原因,并且在创建数据表时创建了一个名为“Column 1”的空白列。 您可以通过以 i=1 启动循环并在之后删除第 1 列来“修复”此问题,如下所示:
查看更多... 回复:使用 Eval Insert、Eval Expr、Parse 和 Substitute 将一个表达式插入另一个表达式嗨,呃,
它适用于 b 列和 c 列。 “a”没有出现。 相反,会出现一个空的 Column 1。
这就是为什么我尝试将“for 循环”放入 New Table() 内。 但通过这种方法,我只得到公式内的表达式。
您知道如何使用 New Table() 内的公式处理“for 循环”以便一次获取所有必需的列吗?
回复:使用 Eval Insert、Eval Expr、Parse 和 Substitute 将一个表达式插入另一个表达式你好@新手,
您需要告诉 JMP 在将该表达式放入公式之前对其进行计算,因为一旦进入列公式,它就不再知道如何引用您的其他表。 使用我喜欢的方法(上面的方法),可能看起来像这样:
Names Default To Here( 1 ); //
//Table with columns you want to create
mydt = New Table( "Source",
Add Rows( 3 ),
New Column( "Name", Character, "Nominal", Set Values( {"a", "b", "c"} ) ),
New Column( "Mean", Numeric, "Continuous", Format( "Best", 12 ),
Set Values( [1, 2, 3] ) ),
New Column( "Std Dev", Numeric, "Continuous", Format( "Best", 12 ),
Set Values( [0.5, 0.6, 0.7] ) )
);
my_newdt = New Table( "Target", Add Rows( 100 ) );
// For loop. Add Columns
For( i = 2, i <= N Rows( mydt ), i++, //
Eval( Eval Expr(
my_newdt << New Column( Column( mydt, 1 )[i],
Numeric,
"Continuous",
Format( "Best", 6 ),
Formula( Random Normal( Expr( As Column( mydt, :Mean )[i] ), Expr( As Column( mydt, :Std Dev )[i] ) ) )//
)
) )
);
回复:使用 Eval Insert、Eval Expr、Parse 和 Substitute 将一个表达式插入另一个表达式创建一个表,其中列中包含公式 - Random Normal() - 来自外部 jmp
我已经为我的问题找到了可行的解决方案。 链接如上。
然而,我非常想让我的代码正常工作。
这个帖子似乎回应了我的主题。
我尝试了上述一些技术。 但这不起作用或者我不明白。
你有什么建议给我吗? 如何获得表达“作为列(mydt,:平均值)[1] “决心寻找源值?
//not working
Clear Globals();
Names Default To Here( 1 ); //
mydt = Current Data Table();
// New data table
my_newdt = New Table( "Table Name",
// Add Rows( N Rows( mydt ) ), // row count can be set by hand e.g. 1000
Add Rows( 10 ), // row count can be set by hand e.g. 1000
New Column( Column( mydt, 1 )[1], // Loop i==1
Numeric,
"Continuous",
Format( "Best", 6 ),
Formula( Random Normal( As Column( mydt, :Mean )[1], 0.01))// As Column(mydt, :Mean )[1] is evalueted in the target table. But Formula has the expression "As Column( mydt, :Mean )[1]" instead of a value from source table
)
);// End New data table
/*// For loop. Add Columns
For( i = 2, i <= N Rows( mydt ), i++, //
my_newdt << New Column( Column( mydt, 1 )[i], // Loop i ==2
Numeric,
"Continuous",
Format( "Best", 6 ),
Set Each Value( Random Normal( As Column( mydt, :Mean )[i], As Column( mydt, :Std Dev )[i] ) )//
)
)// End for loop;
;*/
回复:使用 Eval Insert、Eval Expr、Parse 和 Substitute 将一个表达式插入另一个表达式很有用!
回复:使用 Eval Insert、Eval Expr、Parse 和 Substitute 将一个表达式插入另一个表达式对可用于动态构造 JSL 表达式的方法进行了精彩回顾。掌握了这一点,一切就相当简单了。