Daniel Anderson Daniel Anderson - 4 months ago 9
R Question

Setting default arguments to `...`

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

Answer

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