The R language has a nifty feature for defining functions that can take a variable number of arguments. For example, the function data.frame takes any number of arguments, and each argument becomes the data for a column in the resulting data table. Example usage:
> data.frame(letters=c("a", "b", "c"), numbers=c(1,2,3), notes=c("do", "re", "mi"))
letters numbers notes
1 a 1 do
2 b 2 re
3 c 3 mi
The function’s signature includes an ellipsis, like this:
function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE,
stringsAsFactors = default.stringsAsFactors())
{
[FUNCTION DEFINITION HERE]
}
I would like to write a function that does something similar, taking multiple values and consolidating them into a single return value (as well as doing some other processing). In order to do this, I need to figure out how to "unpack" the ... from the function’s arguments within the function. I don’t know how to do this. The relevant line in the function definition of data.frame is object <- as.list(substitute(list(...)))[-1L], which I can’t make any sense of.
So how can I convert the ellipsis from the function’s signature into, for example, a list?
To be more specific, how can I write get_list_from_ellipsis in the code below?
my_ellipsis_function(...) {
input_list <- get_list_from_ellipsis(...)
output_list <- lapply(X=input_list, FUN=do_something_interesting)
return(output_list)
}
my_ellipsis_function(a=1:10,b=11:20,c=21:30)
Edit
It seems there are two possible ways to do this. They are as.list(substitute(list(...)))[-1L] and list(...). However, these two do not do exactly the same thing. (For differences, see examples in the answers.) Can anyone tell me what the practical difference between them is, and which one I should use?
I read answers and comments and I see that few things weren’t mentioned:
data.frameuseslist(...)version. Fragment of the code:objectis used to do some magic with column names, butxis used to create finaldata.frame.For use of unevaluated
...argument look atwrite.csvcode wherematch.callis used.As you write in comment result in Dirk answer is not a list of lists. Is a list of length 4, which elements are
languagetype. First object is asymbol–list, second is expression1:10and so on. That explain why[-1L]is needed: it removes expectedsymbolfrom provided arguments in...(cause it is always a list).As Dirk states
substitutereturns “parse tree the unevaluated expression”.When you call
my_ellipsis_function(a=1:10,b=11:20,c=21:30)then...“creates” a list of arguments:list(a=1:10,b=11:20,c=21:30)andsubstitutemake it a list of four elements:First element doesn’t have a name and this is
[[1]]in Dirk answer. I achieve this results using:As above we can use
strto check what objects are in a function.It’s ok. Lets see
substituteversion:Isn’t what we needed. You will need additional tricks to deal with these kind of objects (as in
write.csv).If you want use
...then you should use it as in Shane answer, bylist(...).