Заставьте eval() использовать функциональную среду, а не глобальную среду

РЕДАКТИРОВАТЬ: я не смог поделиться MWE более подходящим для моего варианта использования.

У меня проблемы с получением eval() использовать правильную среду.

> f = function(x) {eval.parent(parse(text = x))}
> h = Vectorize(f, "x")
> g = function() {a = 2; h("a")}
> a = 1
> h("a")
a
1
> g()
a
1

Выше я хочу g() возвращать 2,

Кстати: я прочитал главы Хэдли о средах и нестандартных оценках.

1 ответ

Решение

(Оригинальный вопрос) Это извлечет выражение тела из f и оцените это локально g:

 f = function(x) {eval(parse(text = x))}
 g = function() {a = 2; eval( body(f), envir = list(x="a"))}

> g()
[1] 2

Также можете попробовать это:

>  g = function() {a = 2; eval(call("f", a))}
> g()
[1] 2

Для нижестоящего: считается вежливым объяснять, почему ответ "бесполезен". В противном случае нам остается только гадать, какой аспект (правильность, желательность или???) мог вызвать голосование.

После редактирования: теперь это даст запрошенный результат и, вероятно, менее потенциально оскорбительно для тех, кто придерживается строгой кодировки "морали":

 g = function() {a = 2; environment(h)$FUN(a)}
 g()
#[1] 2

Можно вытащить имена и классы элементов в векторизованной функции:

> ls.str(environment(h))
arg.names :  chr "x"
collisions :  logi FALSE
FUN : function (x)  
FUNV : function (x)  
SIMPLIFY :  logi TRUE
USE.NAMES :  logi TRUE
vectorize.args :  chr "x"
Другие вопросы по тегам