19

在文档中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

4 回答 4

12

?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().

于 2011-07-15T09:25:29.380 回答
6

如果您查看以下代码replicate

> replicate
function (n, expr, simplify = TRUE) 
sapply(integer(n), eval.parent(substitute(function(...) expr)), 
    simplify = simplify)
<environment: namespace:base>

您会看到该函数在父框架中进行评估,其中...您的调用函数不再存在。

于 2011-07-15T10:26:22.387 回答
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
于 2015-04-27T01:05:34.660 回答
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)
于 2018-03-07T15:11:48.117 回答