2011-12-22 6 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 объект программно. В идеале я создаю объект запутанных списков с правильным объектом в них, и, возможно, я вызываю as.language на объект list. Однако это не работает. Например:

# 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

Смежные вопросы