4

I want to call an R function that uses the ... (ellipsis) argument to support an undefined number of arguments:

f <- function(x, ...) {
  dot.args <- list(...)
  paste(names(dot.args), dot.args, sep = "=", collapse = ", ")
}

I can call this function passing the actual arguments predefined during design-time, e. g.:

> f(1, a = 1, b = 2)
[1] "a=1, b=2"

How can I pass actual arguments for ... that I know only at run-time (e. g. input from the user)?

# let's assume the user input was "a = 1" and "b = 2"
# ------
# If the user input was converted into a vector:
> f(1, c(a = 1, b = 2))
[1] "=c(1, 2)"                # wrong result!
# If the user input was converted into a list:
> f(1, list(a = 1, b = 2))
[1] "=list(a = 1, b = 2)"     # wrong result!

The expected output of the dynamically generated f call should be:

[1] "a=1, b=2"

I have found some existing questions on how to use ... but they did not answer my question:

How to use R's ellipsis feature when writing your own function?

Usage of Dot / Period in R Functions

Pass ... argument to another function

Can I remove an element in ... (dot-dot-dot) and pass it on?

R Yoda
  • 8,358
  • 2
  • 50
  • 87
  • `dot.args <- unlist(list(...))` or `dot.args <- c(...)` seem to do what you want – user2957945 Nov 17 '17 at 23:54
  • @user2957945 I am not sure if I understand you right. How can I call `f()` using `dot.args <- unlist(list(...))`? – R Yoda Nov 17 '17 at 23:59
  • 1
    apologies, I misunderstood. I was suggesting rewriting your function using above syntax. Perhaps you want `do.call(f, list(a = 1, b = 2))` - but prob need a check to see if input is a list or vector. – user2957945 Nov 18 '17 at 00:05
  • @user2957945 Strike, it works that easy! Please post this as answer! – R Yoda Nov 18 '17 at 00:08

1 Answers1

5

You can do this by passing the function arguments using do.call. First force to list using as.list.

eg

input <- c(a = 1, b = 2)
do.call(f,  as.list(input))

input <- list(a = 1, b = 2)
do.call(f,  as.list(input))
user2957945
  • 2,353
  • 2
  • 21
  • 40