2011-12-22 46 views
10

Chức năng thay thế trong R tạo đối tượng ngôn ngữ dưới dạng cây mà người ta có thể phân tích cú pháp. Làm thế nào tôi có thể tạo cây từ đầu bằng cách sử dụng danh sách hoặc người nào khác để sau đó cung cấp cho nó để eval?Tạo cây biểu thức trong 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.... 

Tôi muốn biết cách tôi có thể tạo lại đối tượng e1 theo cách lập trình. Lý tưởng nhất là tôi tạo ra một đối tượng của danh sách phức tạp với các đối tượng chính xác trong họ và có lẽ tôi gọi một số as.language trên đối tượng list. Tuy nhiên điều đó không hoạt động. Ví dụ:

# 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 

Một cách là chỉ tạo chuỗi '1 + 1' rồi phân tích cú pháp, nhưng dường như không tạo chuỗi để phân tích lại khi bạn có cây ở nơi đầu tiên !

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

Cảm ơn sự giúp đỡ của bạn!

Trả lời

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

thậm chí tốt hơn, vì vậy tôi chỉ có thể thực hiện 'call ('+' , e1, e2) 'để kết hợp 2 biểu thức với một cộng, hoàn hảo! – tlamadon

7

Có một vài cách bạn có thể xây dựng các biểu thức R theo lập trình. Thuận tiện nhất, nếu nó hoạt động đối với trường hợp của bạn, là bquote:

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

nơi .() là một nghịch đảo-báo giá. Điều này sẽ làm việc cho thực tế bất cứ điều gì, nhưng nếu không, có nhiều cách để tự xây dựng các khối xây dựng cơ bản của biểu thức:

> as.symbol('f') 
f 
> as.call(list(quote(f), 1, 2)) 
f(1, 2) 
> as.call(list(as.symbol('{'), 1, 2)) 
{ 
    1 
    2 
} 
> 
+0

lớn, 'as.call' đã thực sự những gì tôi đang tìm kiếm. Từ 2 biểu thức làm thế nào để kết hợp chúng thành một thứ ba và 'as.call (danh sách (as.symbol ('+'), e1, e2))' hoạt động – tlamadon

Các vấn đề liên quan