2013-09-07 29 views

Trả lời

5

Bí quyết bạn đang tìm kiếm có lẽ là sử dụng do.call cho phép bạn gọi một hàm và xác định các đối số là một danh sách:

wrapperfX <- function(x){ 
    dots<-if(missing(x)){ 
    list() 
    }else{ 
    list(x=x) 
    } 
    do.call(targetf,dots) 
} 

này cho phép bạn chỉ định đối số tên cũng như nếu các yếu tố danh sách có những cái tên .

> do.call(log,list(x=10,base=10)) 
[1] 1 

tương đương với

log(x=10,base=10) 

Nếu chức năng bạn đang gọi được thể hiện trong các điều khoản của dot-dot-chấm, sau đó các đối số tôi sẽ xuất hiện trong cùng một cách như nếu bạn muốn đặt chúng trong cuộc gọi hàm.

[cũng có thể bạn đã có một ngoặc mất tích trong, một cách thích hợp, missing((x){ :)]

+0

Nó hoạt động một cách hoàn hảo. Kể từ khi hàm bao bọc nên rất nhanh, tôi tự hỏi, bao nhiêu hackery này là không hiệu quả; các cuộc gọi chức năng tương đối đắt trong việc xây dựng danh sách R + không phải là miễn phí ... –

2

Nếu chức năng của bạn phụ thuộc vào unevaluated biểu , bạn có thể muốn sử dụng substitute, để tránh đánh giá của ... cuộc gọi bên trong vỏ bánh.

Ví dụ:

f <- function(...) deparse(as.list(substitute(list(...)))[-1L]) 

wrap <- function(x){ 
    L <- if(missing(x)) list() else list(x) 
    do.call(f, L) 
} 

wrap2 <- function(x){ 
    L <- if(missing(x)) list() else list(substitute(x)) 
    do.call(f, L) 
} 

Lưu ý cách wrap2 không "chạm" các đối số:

f(1+2+3)  # "list(1 + 2 + 3)" 
wrap(1+2+3) # "list(6)" 
wrap2(1+2+3) # "list(1 + 2 + 3)" 

Đối với cuộc gọi trống rỗng, họ không thể phân biệt:

f()  # "list()" 
wrap() # "list()" 
wrap2() # "list()" 
+0

Thật tuyệt khi biết. Cảm ơn bạn. –