2011-07-15 44 views
18

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 

就像我說的:該文檔似乎提醒了這一點,但我不明白爲什麼會這樣。

回答

11

?replicate,在示例部分中,明確告訴我們您正在嘗試做的事情不會也不行。在?replicateNote部分,我們有:

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

+0

注意,在本例中,事件的「正確」的方法不能正常工作 - 它被複制'x'次(3)而不是'n'次(5)。 – James

+1

@詹姆斯 - 不在我的系統上。我得到了一個2 * 5的矩陣,用於'bar(5,x = 3)' –

+0

糟糕,我的錯誤。轉錄這些例子時有一個錯字。 – James

6

如果你看一下代碼爲replicate

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

您將看到該功能在父框架,其中從調用函數的...不復存在評估。

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