在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
就像我说的:文档似乎警告过这个,但我不明白为什么会这样。
答案 0 :(得分:12)
?replicate
明确告诉我们您尝试做的事情不会也不会起作用。在Note
的{{1}}部分,我们有:
?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()
参数相关,不一定与...
相关。
答案 1 :(得分:6)
如果查看replicate
的代码:
> replicate
function (n, expr, simplify = TRUE)
sapply(integer(n), eval.parent(substitute(function(...) expr)),
simplify = simplify)
<environment: namespace:base>
您会看到在父框架中评估该函数,其中您的调用函数中的...
不再存在。
答案 2 :(得分:1)
实际上有一种方法可以做到这一点:
# 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
答案 3 :(得分:0)
另一种方法:
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)