Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R: using ellipsis argument (...)

Tags:

r

ellipsis

I want to create a wrapper function replacing some of the default arguments.

Here the core of the problem I'm struggling with:

Error in localWindow(xlim, ylim, log, asp, ...) : 
  formal argument "cex" matched by multiple actual arguments

Now a bit of a context. Suppose I define a wrapper function for plot like this:

myplot <- function(x, ... ) {
    plot(x, cex= 1.5, ... )
}

If I call myplot( 1:10, cex= 2 ) I will get the above error. I know I can turn ... to a list

l <- list(...)

and then I could do

if( is.null( l[["cex"]] ) ) l[["cex"]] <- 2

However, how can I "insert" this list back to the ellipsis argument? Something like (I know this won't work):

... <- l

EDIT: I could use defaults in myplot definition (as suggested in the answer from @Thomas), but I don't want to: the function interface will become cluttered. I guess I could define a helper function like that:

 .myfunchelper <- function( x, cex= 2.0, ... ) {
   plot( x, cex= cex, ... )
 }

 myfunc <- function( x, ... ) {
    .myfunchelper( x, ... )
 }

But (i) it is less elegant and (ii) doesn't satisfy my curiosity.

like image 900
January Avatar asked Jun 30 '13 12:06

January


1 Answers

AN ACTUAL ANSWER:

You can do this through a bit of trickery. First, define your function as before, but include a list with your default arguments inside the function. Then you can parse whatever arguments come in through ... as a list, replace the defaults with anything in ... and then pass the updated list of arguments through do.call.

myplot <- function(x, ...) {
    args1 <- list(cex=4, main="Default Title") # specify defaults here
    inargs <- list(...)
    args1[names(inargs)] <- inargs
    do.call(plot, c(list(x=x), args1))
}

myplot(x=1:3) # call with default arguments
myplot(x=1:3, cex=2, main="Replacement", xlab="Test xlab") # call with optional arguments

EARLIER COMMENTARY:

The problem here can be seen through a few example functions:

myplot1 <- function(x, ... ) {
    plot(x, cex= 1.5, ... )
}

myplot2 <- function(x, cex=3, ... ) {
    plot(x, cex=cex, ... )
}

myplot3 <- function(x, ... ) {
    plot(x, ... )
}

myplot1(1:3, cex=3) # spits your error
myplot2(1:3, cex=3) # works fine
myplot3(1:3, cex=3) # works fine

In myplot2, you specify a default value of cex but can change it. In myplot3, cex is simply passed through. If you run myplot2 with two cex arguments, you'll see what's happening with your function (myplot1):

myplot2(1:3, cex=3, cex=1.5) # same error as above

So, you're probably best to avoid setting any defaults in plot(), so then you can pass anything through the ... in myplot.

like image 179
Thomas Avatar answered Sep 30 '22 02:09

Thomas