2011-07-15 36 views
18

Trong tài liệu của sapplyreplicate có một cảnh báo liên quan đến sử dụng ...Sử dụng "..." và 'tái tạo'

Bây giờ, tôi có thể chấp nhận nó như vậy, nhưng muốn hiểu những gì đằng sau nó. Vì vậy, tôi đã tạo ví dụ này ít gây tranh cãi:

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) 

Có lẽ tôi đã làm điều gì đó rõ ràng khủng khiếp sai, nhưng tôi thấy kết quả của điều này khá khó chịu. Vì vậy, bất cứ ai có thể giải thích cho tôi tại sao, trong tất cả các cuộc gọi trên để outerfunction, tôi nhận được kết quả này:

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 

Như tôi đã nói: các tài liệu dường như để cảnh báo cho điều này, nhưng tôi không hiểu tại sao đây là quá .

Trả lời

11

?replicate, trong phần Ví dụ, cho chúng tôi biết rõ ràng rằng những gì bạn đang cố gắng làm không và sẽ không hoạt động. Trong phần Note của ?replicate ta có:

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

Và nếu chúng ta nhìn vào ví dụ, chúng ta thấy:

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

đọc của tôi về các tài liệu là họ làm nhiều hơn so với cảnh báo bạn về việc sử dụng ... trong các cuộc gọi replicate(); họ rõ ràng tài liệu rằng nó không hoạt động. Phần lớn cuộc thảo luận trong tệp trợ giúp đó liên quan đến đối số ... của các chức năng khác, không nhất thiết phải là replicate().

+0

Lưu ý rằng trong ví dụ này, sự kiện "đúng" cách không hoạt động đúng - nó được nhân đôi 'x' lần (3) thay vì' n' lần (5). – James

+1

@James - không có trên hệ thống của tôi. Tôi nhận được ma trận 2 * 5 cho 'bar (5, x = 3)' –

+0

Rất tiếc, lỗi của tôi. Đã có lỗi đánh máy khi sao chép các ví dụ. – James

6

Nếu bạn nhìn vào các mã cho replicate:

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

Bạn thấy rằng các chức năng được đánh giá trong khung phụ huynh, nơi ... từ chức năng gọi điện thoại của bạn không còn tồn tại.

1

Có thực sự là một cách để làm điều này:

# 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

Một cách khác để làm điều đó:

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) 
Các vấn đề liên quan