Japhir
Japhir

Reputation: 564

How to let R recognize a vector of arguments in the ellipsis?

I'm trying to work smartly with the ellipsis (...) argument in R and have some problems.

I am trying to pass some default arguments at the beginning of the function without cluttering up the argument area of the function by using ... and overriding if they are provided there. But somehow the ellipsis argument doesn't seem to pick up my full vector

test <- function(dat, 
                 # I don't want to have to put default col, 
                 # ylim, ylab, lty arguments etc. here
                 ...) {
  # but here, to be overruled if hasArg finds it
  color <- "red"
  if(hasArg(col)) {  # tried it with both "col" and col
    message(paste("I have col:", col))
    color <- col
  }
  plot(dat, col = color)
}

Function call:

test(data.frame(x = 1:10, y = 11:20), col = c("purple", "green", "blue"))

Throws the error:

Error in paste("I have col:", col) (from #8) : 
  cannot coerce type 'closure' to vector of type 'character'

So something is going wrong here. If I pass the ellipsis arguments to the plot function immediately it does work without error.

Upvotes: 3

Views: 1043

Answers (1)

Zheyuan Li
Zheyuan Li

Reputation: 73315

You need to do this, by collecting/packing ... into a list, if you want to use its contents inside the function.

test <- function(dat, 
                 # I don't want to have to put default col, 
                 # ylim, ylab, lty arguments etc. here
                 ...) {
  opt <- list(...)
  color <- "red"
  if(!is.null(opt$col)) {  # tried it with both "col" and col
    message(paste("I have col:", opt$col))
    color <- opt$col
  }
  plot(dat, col = color)
}

test(data.frame(x = 1:10, y = 11:20), col = c("purple", "green", "blue"))

The problem in your original code, is that args() or hasArg() only works for formal arguments in function call. So when you pass in col = c("purple", "green", "blue"), hasArg() knows there is a formal argument col, but does not evaluate it. Therefore, inside the function, there is no actual col variable to be found (you can use a debugger to verify this). Interestingly, there is a function col() from R base package, so this function is passed to paste. As a result, you get an error message when trying to concatenate a character string and a "closure".

Upvotes: 5

Related Questions