Использование "..." и "копия"
В документации sapply
а также replicate
есть предупреждение об использовании ...
Теперь я могу принять это как таковое, но хотел бы понять, что за этим стоит. Итак, я создал этот маленький надуманный пример:
innerfunction<-function(x, extrapar1=0, extrapar2=extrapar1)
{
cat("x:", x, ", xp1:", extrapar1, ", xp2:", extrapar2, "\n")
}
middlefunction<-function(x,...)
{
innerfunction(x,...)
}
outerfunction<-function(x, ...)
{
cat("Run middle function:\n")
replicate(2, middlefunction(x,...))
cat("Run inner function:\n")
replicate(2, innerfunction(x,...))
}
outerfunction(1,2,3)
outerfunction(1,extrapar1=2,3)
outerfunction(1,extrapar1=2,extrapar2=3)
Возможно, я сделал что-то очевидное ужасно неправильно, но я нахожу результат этого довольно огорчительным. Так может кто-нибудь объяснить мне, почему во всех вышеперечисленных outerfunction
Я получаю этот вывод:
Run middle function:
x: 1 , xp1: 0 , xp2: 0
x: 1 , xp1: 0 , xp2: 0
Run inner function:
x: 1 , xp1: 0 , xp2: 0
x: 1 , xp1: 0 , xp2: 0
Как я уже сказал: документы, кажется, предупреждают об этом, но я не понимаю, почему это так.
4 ответа
?replicate
в разделе "Примеры" прямо говорится, что то, что вы пытаетесь сделать, не работает и не будет работать. в Note
раздел ?replicate
у нас есть:
If ‘expr’ is a function call, be aware of assumptions about where
it is evaluated, and in particular what ‘...’ might refer to. You
can pass additional named arguments to a function call as
additional named arguments to ‘replicate’: see ‘Examples’.
И если мы посмотрим на примеры, мы увидим:
## use of replicate() with parameters:
foo <- function(x=1, y=2) c(x,y)
# does not work: bar <- function(n, ...) replicate(n, foo(...))
bar <- function(n, x) replicate(n, foo(x=x))
bar(5, x=3)
Мое чтение документов заключается в том, что они делают гораздо больше, чем предупреждают вас об использовании ...
в replicate()
звонки; они явно документируют, что это не работает. Большая часть обсуждения в этом файле справки относится к ...
аргумент других функций, не обязательно replicate()
,
Если вы посмотрите на код для replicate
:
> replicate
function (n, expr, simplify = TRUE)
sapply(integer(n), eval.parent(substitute(function(...) expr)),
simplify = simplify)
<environment: namespace:base>
Вы видите, что функция оценивается в родительском кадре, где ...
от вашей вызывающей функции больше не существует.
На самом деле есть способ сделать это:
# Simple function:
ff <- function(a,b) print(a+b)
# This will NOT work:
testf <- function(...) {
replicate(expr = ff(...), n = 5)
}
testf(45,56) # argument "b" is missing, with no default
# This will:
testf <- function(...) {
args <- as.list(substitute(list(...)))[-1L]
replicate(expr = do.call(ff, args), n = 5)
}
testf(45,56) # 101
Альтернативный способ сделать это:
g <- function(x, y) x + y
f <- function(a = 1, ...) {
arg_list <- list(...)
replicate(n = 3, expr = do.call(g, args = arg_list))
}
f(x = 1, y = 2)