Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting default arguments to `...`

Tags:

r

I have a function where I'm passing ... to plot, so the user can add additional arguments. For some of these optional arguments, I'd like to setup default values, without declaring them as formal arguments in the function. Here's a simple example

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

Then I can run simpleFun(rnorm(10), rnorm(10), xlim = c(-1, 1)) or simpleFun(rnorm(10), rnorm(10)) and xlim will be c(-1, 1) in the first example (defined by user) and c(-6, 6) in the second (not defined by user). The problem, of course, is that ... is now not going anywhere. I'd like to specify it more like

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), ...)
}

so that any additional argument can be passed to plot, but then calling simpleFun(rnorm(10), rnorm(10), xlim = c(-1, 1)) won't work because there will be two xlim arguments supplied to plot.

So, basically, I'm wondering if there's a way to set default values for any arguments passed through ...? I realize the way I've defined things above is probably less than ideal, but it's the best I've come up with at this point (which still doesn't work).

like image 577
Daniel Anderson Avatar asked Aug 04 '16 16:08

Daniel Anderson


1 Answers

I think this one calls for do.call(). Notice I have renamed your default arguments x and y to match those for arguments 1 and 2 in plot(). If you want to continue to use a and b, uncomment the fourth line. But it will make things a lot easier if you stick with the default names.

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

This seems to work fine on these sample runs.

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))
like image 67
Rich Scriven Avatar answered Oct 05 '22 08:10

Rich Scriven