2011-12-22 14 views
10

La función de sustitución en R crea un objeto de lenguaje en forma de un árbol que se puede analizar. ¿Cómo puedo crear el árbol desde cero usando list o else para dárselo a eval?Crear árbol de expresiones en 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.... 

me gustaría saber cómo puedo reconstruir el objeto e1 mediante programación. Idealmente creo un objeto de listas intrincadas con el objeto correcto en ellas y tal vez llamo a algunos as.language en el objeto list. Sin embargo, eso no funciona. Por ejemplo:

# 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 

Una forma es simplemente generar la cadena '1 + 1' y luego analizarlo, pero no parece elegante para generar cadenas de analizar de nuevo cuando se tiene el árbol en el primer lugar !

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

Gracias por su ayuda!

Respuesta

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

incluso mejor, así que puedo hacer 'call ('+' , e1, e2) 'para combinar 2 expresiones con un plus, ¡perfecto! – tlamadon

7

Hay algunas maneras en que puede construir expresiones R programáticamente. La forma más conveniente, si funciona para su caso, es bquote:

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

donde .() es una inversa comilla. Esto debería funcionar para prácticamente cualquier cosa, pero si no es así, hay maneras de construir manualmente los bloques de construcción básicos de las expresiones:

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

grandes, 'as.call' en realidad era lo que estaba buscando. A partir de 2 expresiones cómo combinarlas en una tercera y 'as.call (list (as.symbol ('+'), e1, e2))' funciona – tlamadon

Cuestiones relacionadas