Создание дерева выражений в R - PullRequest
11 голосов
/ 23 декабря 2011

Функция замены в 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 

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

Ответы [ 2 ]

8 голосов
/ 23 декабря 2011

Есть несколько способов, которыми вы можете программно создавать выражения 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
}
> 
7 голосов
/ 23 декабря 2011
> 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
...