在R中操纵表达式

时间:2012-03-02 16:31:53

标签: r expression

我正在寻找一种创建表达式的方法,该表达式是两个给定表达式的乘积。例如,假设我有

e1 <- expression(a+b*x)
e2 <- expression(c+d*x)

现在我想以编程方式创建表达式(e1)*(e2)

expression((a+b*x)*(c+d*x))

背景 我正在写一个模型拟合函数。该模型有两个用户定义的部分。我需要能够单独“处理”它们,然后创建一个组合表达式并将其“处理”为一个模型。 “处理”涉及采用数字导数,deriv函数需要表达式作为输入。

3 个答案:

答案 0 :(得分:5)

试试这个:

e1 <- quote(a+b*x)   # or expression(*)[[1]]
e2 <- quote(c+d*x)
substitute(e1 * e2, list(e1=e1, e2=e2))

答案 1 :(得分:5)

我不经常处理这个问题,但这样的事情似乎正在发挥作用

e1 <- expression(a + b*x)
e2 <- expression(c + d*x)
substitute(expression(e1*e2), list(e1 = e1[[1]], e2 = e2[[1]]))
# expression((a + b * x) * (c + d * x))

答案 2 :(得分:2)

你的情况可能有些过分,但是Ryacas包可以很好地执行这种更复杂的符号操作:

library(Ryacas)
yacas(expression(e1*e2))$text
# expression((a + b * x) * (c + d * x))

此外,您可以在基础R中构建相同的表达式,而不是使用substitute(),而不是这样:

as.expression(as.call(list(as.symbol("*"), e1[[1]], e2[[1]])))
# expression((a + b * x) * (c + d * x))

解释性说明:处理expression个对象最初令人困惑的一个方面是,它们实际上是列表的语言对象 - 即使是(通常情况下)案例)这些列表只包含一个对象。例如,在您的问题中,e1e2都是长度为1的列表,每个列表包含一个call个对象。

从内到外,使用上面的代码:

  1. 使用call
  2. 提取两个[[1]]个对象
  3. 使用as.call()构建一个新调用,该调用是两个call对象的产物。
  4. 最后,将结果call包装为您想要的expression对象。