R: using the ellipsis argument (...)

I want to create a wrapper function that replaces some default arguments.

Here's 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 little context. Suppose I define a wrapper function for a graph as follows:

 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 ... into a list

 l <- list(...) 

and then I could do

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

However, how can I β€œpaste” this list back into the ellipsis argument? Something like (I know this won't work):

 ... <- l 

EDIT: I could use the default values ​​in myplot definition (as suggested in the answer from @Thomas), but I don't want to: the function interface will be cluttered. I think I could define a helper function:

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

But (i) he is less elegant and (ii) does not satisfy my curiosity.

+7
source share
1 answer

ACTUAL ANSWER:

You can do this through a little cheating. First, define your function as before, but include a list with default arguments inside the function. You can then parse all the arguments using ... as a list, replace the defaults with something in ... , and then pass the updated argument list via 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 

COMMENT EARLIER:

The problem here is manifested in several examples of 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 the default value of cex , but you can change it. In myplot3 , cex just passed. If you run myplot2 with two cex arguments, you will see what happens to your function ( myplot1 ):

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

So, you're probably better off not setting defaults to plot() , so you can pass something through ... to myplot .

+11
source

All Articles