2016-12-08 7 views
-1

У меня есть пользовательские R средыВложенные функции синтаксического анализа (Eval (...), Envir = пользовательских)

e = new.env() 
e[["a"]] = function(x) b(x) 
e[["b"]] = function(x) x + 1 

Функция b() работает, как ожидалось.

> eval(parse(text = "b(1)"), envir = e) 
[1] 2 

Но a(1) вызывает ошибку.

> eval(parse(text = "a(1)"), envir = e) 
Error in a(1) : could not find function "b" 

Как я могу получить eval(parse(text = "a(1)"), envir = e)?

+1

Идеальный подход заключается в том, чтобы избежать 'eval (parse (...))'. Каков ваш фактический прецедент для этого? – nrussell

ответ

3

Ваша проблема в том, что функции в R отслеживают среду, в которой они были созданы. Когда вы вызываете оператор function() вне любого другого контекста, эта функция создается в глобальной среде, а затем вы назначаете эту функцию в другую среду, но она не изменяется там, где она была изначально определена. Наблюдайте

e = new.env() 
e[["a"]] = function(x) b(x) 

environment(e[["a"]]) 
# <environment: R_GlobalEnv> 

identical(e, environment(e[["a"]])) 
# [1] FALSE 

Так что функция будет по-прежнему использовать глобальную окружающую среду (не e среды) для разрешения символов. Вы можете явно изменить среду с

environment(e[["a"]]) <- e 

или просто создать его в окружающей среде, в первую очередь с evalq

evalq(a <- function(x) b(x), e) 
evalq(b <- function(x) x + 1, e) 

identical(e, environment(e[["a"]])) 
# [1] TRUE 

Но вы уверены, что это действительно лучший дизайн для вашей проблемы? Кажется немного тупым. Видение eval(parse()) обычно является предупреждающим знаком.