2016-08-04 26 views
6

Tôi có chức năng tôi đang chuyển ... đến plot, để người dùng có thể thêm đối số bổ sung. Đối với một số đối số tùy chọn này, tôi muốn thiết lập các giá trị mặc định, mà không khai báo chúng như là các đối số chính thức trong hàm. Dưới đây là một ví dụ đơn giảnĐặt đối số mặc định thành `...`

simpleFun <- function(a, b,...) { 
    args <- as.list(match.call()) 
    if(is.null(args$xlim)) args$xlim <- quote(c(-6, 6)) 

    plot(a, b, xlim = eval(args$xlim)) 
} 

Sau đó, tôi có thể chạy simpleFun(rnorm(10), rnorm(10), xlim = c(-1, 1)) hoặc simpleFun(rnorm(10), rnorm(10))xlim sẽ c(-1, 1) trong ví dụ đầu tiên (được định nghĩa bởi người sử dụng) và c(-6, 6) trong lần thứ hai (không được định nghĩa bởi người sử dụng). Vấn đề, tất nhiên, là ... hiện không đi đâu cả. Tôi muốn xác định nó giống như

simpleFun2 <- function(a, b,...) { 
    args <- as.list(match.call()) 
    if(is.null(args$xlim)) args$xlim <- quote(c(-6, 6)) 

    plot(a, b, xlim = eval(args$xlim), ...) 
} 

để cho bất kỳ đối số bổ sung có thể được truyền cho plot, nhưng sau đó gọi simpleFun(rnorm(10), rnorm(10), xlim = c(-1, 1)) sẽ không làm việc vì sẽ có hai xlim đối số cung cấp cho plot.

Vì vậy, về cơ bản, tôi tự hỏi liệu có cách nào để đặt giá trị mặc định cho bất kỳ đối số nào được chuyển qua ... không? Tôi nhận ra cách tôi đã xác định những điều trên có lẽ ít hơn lý tưởng, nhưng nó là tốt nhất tôi đã đưa ra tại thời điểm này (mà vẫn không hoạt động).

+1

@RichardScriven Và lý tưởng chỉ định 'envir = parent.frame()' để đảm bảo rằng nó được đánh giá khi người dùng gọi hàm. –

+0

@RichardScriven Tôi thích ý nghĩ đó, nhưng dường như nó không có tác dụng với tôi. Nếu tôi thay thế 'lô (a, b, xlim = eval (args $ xlim), ...)' với 'do.call (" cốt truyện ", c (args, ...))' Tôi nhận được 'Lỗi trong lô (x, a = x, xlim = c (-6, 6)): đối tượng 'x' không tìm thấy' (cùng với cảnh báo bổ sung). Lưu ý rằng tôi nhận được cùng một lỗi khi bao gồm 'envir = parent.frame()'. –

+0

Hmm ... Khi tôi chạy 'simpleFun2 (rnorm (10), rnorm (10))' (sử dụng mã của bạn) các giới hạn của trục x kết thúc lên 'c (-1, 1.5)', thay vì ' c (-6, 6) 'nó phải mặc định. –

Trả lời

2

Tôi nghĩ điều này yêu cầu do.call(). Lưu ý rằng tôi đã đổi tên đối số mặc định của bạn xy để khớp với đối số 1 và 2 trong plot(). Nếu bạn muốn tiếp tục sử dụng ab, hãy bỏ ghi chú dòng thứ tư. Nhưng nó sẽ làm mọi thứ trở nên dễ dàng hơn rất nhiều nếu bạn gắn bó với tên mặc định.

simpleFun <- function(x, y, ...) { 
    args <- as.list(match.call()[-1]) 
    if(!any(names(args) == "xlim")) 
     args$xlim <- c(-6, 6) 
    ## names(args)[1:2] <- c("x", "y") 
    do.call("plot", args) 
} 

Điều này dường như hoạt động tốt trên các lần chạy mẫu này.

simpleFun2(a = rnorm(10), b = rnorm(10)) 
simpleFun2(a = rnorm(10), b = rnorm(10), xlim = c(-1, 1)) 
simpleFun2(a = rnorm(10), b = rnorm(10), xlim = c(-1, 1), ylim = c(-4, 4)) 
+0

Cảm ơn bạn rất nhiều! –

+2

Không giống như hầu hết các arg, tôi đoán điều này phải được viết ra đầy đủ.Tôi có thể viết 'cốt truyện (rnorm (10), rnorm (10), xli = c (-6,6))' nhưng không phải 'simpleFun (rnorm (10), rnorm (10), xli = c (-6,6)) ' – Frank

+1

Chỉ trong trường hợp nó hữu ích cho người khác, tôi cũng phải áp dụng điều này vào một ô mật độ, và có một chút khác biệt ở đó vì lý tưởng hàm chỉ yêu cầu một đối số (đối tượng để tính mật độ). Trong trường hợp đó, tôi thấy những điều sau đây hoạt động tốt, sử dụng phương pháp hơi khác để tạo 'args'. 'densPlotEx <- chức năng (a, ...) { \t args <- danh sách ("x" = quote (mật độ (a)), ...) \t if (is.null (args $ xlim)) { \t \t \t args $ xlim <- quote (c (-6, 6)) \t \t} \t \t do.call (cốt truyện, args) } ' –

Các vấn đề liên quan