使用“...”和“复制”

时间:2011-07-15 08:40:58

标签: r ellipsis replicate sapply

sapplyreplicate的文档中,有关于使用...的警告

现在,我可以接受它,但想了解背后的原因。所以我创造了这个有点人为的例子:

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 个答案:

答案 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)