Using "..." and "replicate"

r ellipsis replicate sapply

6312 观看

4回复

9996 作者的声誉

In the documentation of sapply and replicate there is a warning regarding using ...

Now, I can accept it as such, but would like to understand what is behind it. So I've created this little contrived example:

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)

Perhaps I've done something obvious horribly wrong, but I find the result of this rather upsetting. So can anyone explain to me why, in all of the above calls to outerfunction, I get this output:

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

Like I said: the docs seem to warn for this, but I do not see why this is so.

作者: Nick Sabbe 的来源 发布者: 2011 年 7 月 15 日

回应 (4)


12

143118 作者的声誉

决定

?replicate, in the Examples section, tells us explicitly that what you are trying to do does not and will not work. In the Note section of ?replicate we have:

     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’.

And if we look at Examples, we see:

 ## 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)

My reading of the docs is that they do far more than warn you about using ... in replicate() calls; they explicitly document that it does not work. Much of the discussion in that help file relates to the ... argument of the other functions, not necessarily to replicate().

作者: Reinstate Monica - G. Simpson 发布者: 15.07.2011 09:25

6

54458 作者的声誉

If you look at the code for replicate:

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

You see that the function is evaluated in the parent frame, where the ... from your calling function no longer exists.

作者: James 发布者: 15.07.2011 10:26

1

2333 作者的声誉

There actually is a way to do this:

# 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
作者: Antoine Lizée 发布者: 27.04.2015 01:05

0

6 作者的声誉

An alternative way to do that:

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)
作者: irudnyts 发布者: 07.03.2018 03:11
32x32