Создание дерева выражений в R

Подстановка функции в R создает объект языка в виде дерева, которое можно разбор. Как я могу создать дерево с нуля с помощью списка или еще, чтобы затем дать ему eval?

# 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 

Спасибо за вашу помощь!

Ответ 1

> 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

Ответ 2

Существует несколько способов программирования выражений 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
}
>