R имеет функции, которые не полностью согласованы.Например, min
и max
принимают произвольное количество аргументов, где все нераспознанные аргументы учитываются в математическом расчете.mean
это не так, он должен иметь все числа, которые должны рассматриваться как первый (или именованный x=
) аргумент.
min(1,20,0)
# [1] 0
min(c(1,20,0))
# [1] 0
mean(1,20,0) # might not be what one would expect
# [1] 1
mean(c(1,20,0))
# [1] 7
Для любопытных, 20 и 0 не игнорируются, первый mean
вызов интерпретируется как mean(0, trim=20, na.rm=0)
(где na.rm=0
фактически совпадает с na.rm=FALSE
).
Ваше использование call
немного отклонено.Из справки ?call
,
вызов возвращает неоцененный вызов функции
, который на самом деле вам не поможетмного.Вы можете сделать eval(call(...))
, но это выглядит глупо в свете этой следующей функции.
Использование do.call
немного более прямолинейно.В качестве первого аргумента я могу взять: функцию (анонимную или именованную) или символьную строку, которая соответствует функции.На самом деле существуют различия в скорости между использованием одного или другого, поэтому я склонен использовать character
ссылку на имя функции, когда это возможно.(Я не помню ссылку, которая количественно оценивает это утверждение, я включу его, если скоро его найду.)
Для функций, подобных min
выше, которые могут принимать любое количество аргументов, можно сделать это:
args <- c(1,20,0)
as.list(args)
# [[1]]
# [1] 1
# [[2]]
# [1] 20
# [[3]]
# [1] 0
do.call("min", as.list(args)) # == min(1,20,0)
# [1] 0
list(args)
# [[1]]
# [1] 1 20 0
do.call("min", list(args)) # == min(c(1,20,0))
# [1] 0
Однако для mean
и аналогичных вам необходимо принудительно настроить последнее поведение:
do.call("mean", list(args)) # == mean(c(1,20,0))
# [1] 7
Чтобы вызвать функцию с аргументами, определенными программно, вам необходимоиспользовать do.call
.