Я думаю, что ответ @joran правильный, но, может быть, я могу попытаться объяснить по-другому.
«Функция» (
в R по сути является функцией тождества. Он отражает то, что вы передаете ему. Его почти как нет. Нет никакой разницы между тем, что будет возвращено этими операторами
x #1
(x) #2
((x)) #3
Скобка просто передает значение внутри. Вы можете добавить столько круглых скобок, сколько хотите, и это не изменит того, что возвращается. Оценщик смотрит на ((x))
, видит внешнюю скобку и знает, что нужно просто вернуть значение вещи внутри скобки. Итак, теперь он анализирует только (x)
и снова видит внешнюю скобку и просто возвращает значение внутри скобки, то есть x
. Скобка просто передает значение изнутри; они не оценивают это.
Голое значение x
— это имя (или символ). Имя не связано однозначно со значением. Сопоставление между именами и значениями зависит от среды. Вот почему имена должны оцениваться в определенном контексте, чтобы получить значение. Рассмотрим эти примеры
aa <- 5
dd <- data.frame(aa=20)
x <- as.name("aa")
foo <- function(x) {aa<-10; eval(x)}
eval(x)
# [1] 5
foo(x)
# [1] 10
eval(x, dd)
# [1] 20
Такое поведение на самом деле очень желательно. Это то, что заставляет функции, требующие нестандартной оценки, например
subset(mtcars, hp<100)
Когда вы используете консоль R, она ведет себя как REPL -- он читает ваш ввод, оценивает его, печатает, а затем ожидает следующего ввода. Обратите внимание, что он выполняет только один уровень оценки, и оценка происходит в «текущей» среде. Он не оценивает рекурсивно возвращаемое значение из выражения. Итак, когда вы делаете
x <- as.name("aa")
x # identical to (x)
# aa
когда REPL доходит до шага оценки, он оценивает имя x
, которое указывает на имя aa
. Вот и все. Один уровень оценки. Имя aa
впоследствии не оценивается.
На странице справки ?eval
есть примечание:
eval оценивает свой первый аргумент в текущей области перед тем, как передать его оценщику
Там не происходит «двойной» оценки. Он просто оценивает свои параметры, как и любая другая функция в R. Например
aa <- 5
bar <- function(x) print(x)
bar(aa+2)
# [1] 7
Он печатает «7», а не «аа+2», потому что функция оценила свой параметр перед печатью. Это также объясняет различия между этими двумя
dd <- data.frame(bb=20)
xx <- as.name("bb")
eval(bb, dd)
# Error in eval(bb, dd) : object 'bb' not found
eval(xx, dd)
# [1] 20
При первом вызове eval()
R не может оценить bb
в текущей среде, поэтому вы получаете ошибку. Но обратите внимание, что
evalq(bb, dd)
работает, потому что evalq
не пытается вычислить первый параметр выражения.
person
MrFlick
schedule
17.05.2016
get
делать то, что делаетeval
, но тогда ответ должен был бы быть, потому что они делают две разные вещи: одна вычисляет выражение (которое может быть символом), а другая извлекает объекты где вы указываете имя (символ) объекта через символ. Почему бы не разделить разные функции на две разные функции? - person joran   schedule 07.05.2016