2011-12-22 116 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