在 R 中创建表达式树

Posted

技术标签:

【中文标题】在 R 中创建表达式树【英文标题】:Creating expression tree in R 【发布时间】:2011-12-22 22:12:30 【问题描述】:

R 中的替代函数以可以解析的树的形式创建语言对象。如何使用列表从头开始创建树,然后将其提供给 eval?

# substitute gives a tree representation of the expression
a=1; b=2;
e1 = substitute(a+2*b)
eval(e1)      #gives 5 as expected
e1            # is type language
e1[[1]]       # this is `+`
e1[[2]]       # this is 'a' type symbol
e1[[3]]       # this is type language
e1[[3]][[1]]  # this is `*`  etc....

我想知道如何以编程方式重建e1 对象。理想情况下,我创建一个包含正确对象的复杂列表对象,也许我在list 对象上调用了一些as.language。然而,这是行不通的。例如:

# how to construct the tree?
eval(list(as.symbol('+'),1,1))                # does not return 2
eval(as.expression(list(as.symbol('+'),1,1))) # does not return 2

一种方法是只生成字符串 '1+1' 然后解析它,但是当你首先拥有树时生成字符串来再次解析它们似乎并不优雅!

eval(parse(text='1+1')) # does return 1, but not elegant if tree is 
                        # large and already in memory 

感谢您的帮助!

【问题讨论】:

【参考方案1】:

您可以通过多种方式以编程方式构造 R 表达式。如果适用于您的情况,最方便的是bquote

> a = 1
> bquote(.(a) + .(a))
1 + 1

.() 是一个反引号。这几乎适用于任何事情,但如果不适用,有一些方法可以手动构建表达式的基本构建块:

> as.symbol('f')
f
> as.call(list(quote(f), 1, 2))
f(1, 2)
> as.call(list(as.symbol(''), 1, 2))

    1
    2

> 

【讨论】:

太棒了,as.call 正是我想要的。从 2 个表达式如何将它们组合成第三个表达式,as.call(list(as.symbol('+'),e1,e2)) 有效 @tlamadon 请注意,这应该等同于bquote(.(e1) + .(e2))【参考方案2】:
> plus <- .Primitive("+")
> plus
function (e1, e2)  .Primitive("+")
> times=.Primitive("*")
> eval(call("plus", b, call("times",2, b)))
[1] 6
> eval(call("plus", a, call("times",2, b)))
[1] 5

【讨论】:

更好,所以我可以通过call('+',e1,e2) 将 2 表达式与加号结合起来,完美!

以上是关于在 R 中创建表达式树的主要内容,如果未能解决你的问题,请参考以下文章

无法在 R 中创建决策树

在 R 中创建切片树

表达式树

rpart 不在 R 中创建决策树,SVM 有效

带有语句体的 lambda 表达式无法转换为 nopCommerce 中的表达式树 [重复]

如何使用 R 在 cassandra 中创建键空间和表?