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?
list
andc
functions work in this way, but both are primitives, so I can't easily inspect their source code to understand how they work. – Anopheles