2011-12-22 89 views
10

R中的替代函数以可以解析的树形式创建语言对象。我如何使用列表从头开始创建树,然后再将它赋予eval?在R中创建表达式树

# 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 

感谢您的帮助!

回答

6
> 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 
+1

甚至更​​好,所以我只需要'call('+' ,e1,e2)'将2个表达与一个加号相结合,完美! – tlamadon

7

有几种方法可以编程构建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 
} 
> 
+0

很大,'as.call'其实我一直在寻找。从2表达式如何将它们组合成第三个和'as.call(list(as.symbol('+'),e1,e2))'作品 – tlamadon