# A new R trick … for me at least

August 3, 2013
By

(This article was first published on Odd Hypothesis, and kindly contributed to R-bloggers)

What were going to be talking about today are dynamic argument lists for functions. Specifically, how to unpack and prepare them in R using `...`, `list()`, and `do.call()`

### Biased by Matlab and varargin

Initially, I based my use of `...` in R on my experience with Matlab’s `varargin`. Using `varargin`, Matlab functions can have a signature of:

``function f(varargin)% do stuff here``

Functions that use `varargin` are responsible for processing its contents, which is easy since it is simply a cell array. Thus, it can be “unpacked” and modified using cell array methods.

``function f(varargin)arg1 = varargin{1}arg2 = varargin{2}return(arg1*arg2)``

At call, arguments captured by `varargin` can be specified as an expanded cell array:

``args = {foo, bar}f(args{:})``

As a matter of fact, functions that do not use `varargin` can also be called this way since Matlab effectively interprets an expanded cell array as a comma-separated list

This comes in handy when you have a mixture of required and optional arguments for a function.

``f(arg, opts{:})``

### Back to R …

I used to think `...` was analogous to `varargin` since:

• it captures all function arguments not explicitly defined by the call signature
• the number of arguments it captures can vary

However, unlike `varargin`:

• `...` is a special R language expression/object
• it needs to be converted to a list to access the arguments (names and/or values) that it captures

The former point is strength and quirk of R, as it allows for arguments encapsulated in `...` to be passed on to additional functions:

``f = function(x, ...) {  y = g(x, ...)  return(y)}``

The latter point above (unpacking `...`) is actually easy to do:

``f = function(x, ...) {  args = list(...) # contains a=1, b=2  return(args\$a * args\$b)}``

Where confusion arises for many is that `...` is essentially immutable (cannot be changed). While conceptually a `list()`, you can’t modify it directly using list accessors:

``f = function(x, ...) {  ...[[1]] = 3 # this produces an error, as would ...\$var and ...[1]  y = g(x, ...)  return(y)}``

So, what if I wanted to unpack arguments in `...`, check/change their values, and repackage it for another function call? Since `...` is immutable the code below would throw an error.

``f = function(x, ...) {  args = list(...) # unpack, contains a='foo'  args\$a = bar  ... = args # ERROR!  y = g(x, ...)  return(y)}``

Also, there isn’t a way (that I’ve found yet) to unroll a `list()` object in R into a comma-separated list like you can with a cell array in Matlab.

``# this totally doesn't workargs = list(a=1, b='foo')result = f(args[*]) # making up syntax here. would be nice, no?``

As it turns out, `...` doesn’t even come into play here. In fact, you need to use a rather deep R concept – calls.

Whenever a function is used in R, a `call` is produced, which is an unprocessed expression that is then interpreted by the underlying engine. Why the delay? Only the creators/developers of R can fully detail why, but it does allow for some neat effects – e.g. the automatic labeling of plots.

To package a programmatically generated argument list one uses the `do.call()` function:

``result = do.call('fun', list(arg1, arg2, etc, etc))``

where the first argument is the name of the function to call, and the second argument is a list of arguments to pass along. For all intents and purposes, the R statement above is equivalent to the Matlab statement below.

``results = fun(args{:}) % where args = {arg1, arg2, etc, etc}``

Thus, process to unpack `...`, check/modify an argument, and repack for another function call becomes:

``f = function(x, ...) {  args = list(...) # unpack, contains a='foo'  args\$a = bar     # change argument "a"  y = do.call(g, c(x, args)) # repack arguments for call to g()  return(y)}``

I must credit this epiphany to the following StackOverflow question and answer: http://stackoverflow.com/questions/3414078/unpacking-argument-lists-for-ellipsis-in-r

Written with StackEdit.

R-bloggers.com offers daily e-mail updates about R news and tutorials on topics such as: Data science, Big Data, R jobs, visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...