Насколько я понимаю, когда вы явно даете аргументы функции, поведение по умолчанию заключается в оценке указанных аргументов в среде, в которой они были заданы, , а не в среде выполнения функции (как @ ответ Axeman детали).
Можно обойти это (если вы должны - это другое дело). Вы можете использовать комбинацию substitute()
(для захвата неоцененного аргумента) и eval()
, чтобы изменить среду, в которой оценивается аргумент. Здесь мы явно оцениваем b
в среде выполнения foo
:
foo <- function(a, b = length(a)) {
eval(substitute(b), env = environment())
}
(Из-за значений по умолчанию в eval()
было бы достаточно просто написать eval(substitute(b))
. Но иногда приятно быть явным; вот так, гораздо более очевидно, что мы меняем среду оценки.)
Теперь следующее не выдаст ошибку:
foo(a = c(1, 2), b = length(a))
#> [1] 2
Однако , если вы решите пойти по этому пути, вы должны быть очень явными при документировании такой функции, чтобы аргумент b
оценивался в среде выполнения. Например, что должно произойти, когда a
присутствует как в среде, в которой задан аргумент, так и в среде выполнения? Это может быть неожиданным поведением, если оно плохо документировано (и источником трудно диагностируемых ошибок, даже если оно хорошо документировано).
a <- 1:10
foo(a = c(1, 2), b = length(a))
#> [1] 2
Для получения более подробной информации об оценке (и подводных камнях), вы можете проверить главу Evaluation в Advanced R .
Создано в 2018-07-05 пакетом Представ (v0.2.0).