[R] using argument names (of indeterminate number) within a function

Marc Schwartz (via MN) mschwartz at mn.rr.com
Tue Jul 19 18:00:17 CEST 2005


On Tue, 2005-07-19 at 17:29 +0200, Dirk Enzmann wrote:
> Although I tried to find an answer in the manuals and archives, I cannot 
> solve this (please excuse that my English and/or R programming skills 
> are not good enough to state my problem more clearly):
> 
> I want to write a function with an indeterminate (not pre-defined) 
> number of arguments and think that I should use the "..." construct and 
> the match.call() function. The goal is to write a function that (among 
> other things) uses cbind() to combine a not pre-defined number of 
> vectors specified in the function call. For example, if my vectors are 
> x1, x2, x3, ... xn, within the function I want to use cbind(x1, x2) or 
> cbind(x1, x3, x5) or ... depending on the vector names I use in the 
> funcion call. Additionally, the function has other arguments.
> 
> In the archives I found the following thread (followed by Marc Schwartz)
> 
> http://finzi.psych.upenn.edu/R/Rhelp02a/archive/15186.html
> [R] returning argument names from Peter Dalgaard BSA on 2003-04-10 (stdin)
> 
> that seems to contain the solution to my problem, but I am stuck because 
>   sapply(match.call()[-1], deparse) gives me a vector of strings and I 
> don't know how to use the names in this vector in the cbind() function.
> 
> Up to now my (clearly deficit) function looks like:
> 
> test <- function(..., mvalid=1)
> {
>    args = sapply(match.call()[-1], deparse)
> # and here, I don't know how the vector names in args
> # can be used in the cbind() function to follow:
> #
> # temp <- cbind( ???
>    if (mvalid > 1)
>    {
> #  here it goes on
>    }
> }
> 
> Ultimately, I want that the function can be called like
> test(x1,x2,mvalid=1)
> or
> test(x1,x3,x5,mavlid=2)
> and that within the function
> cbind(x1,x2)
> or cbind(x1,x3,x5)
> will be used.
> 
> Can someone give and explain an example / a solution on how to proceed?

Hi Dirk,

How about this:

my.cbind <- function(...)
{
  do.call("cbind", list(...))
}

> a <- 1:10
> b <- 11:20
> c <- 21:30
> d <- 31:40

> my.cbind(a, b)
      [,1] [,2]
 [1,]    1   11
 [2,]    2   12
 [3,]    3   13
 [4,]    4   14
 [5,]    5   15
 [6,]    6   16
 [7,]    7   17
 [8,]    8   18
 [9,]    9   19
[10,]   10   20

> my.cbind(b, c, d)
      [,1] [,2] [,3]
 [1,]   11   21   31
 [2,]   12   22   32
 [3,]   13   23   33
 [4,]   14   24   34
 [5,]   15   25   35
 [6,]   16   26   36
 [7,]   17   27   37
 [8,]   18   28   38
 [9,]   19   29   39
[10,]   20   30   40

> my.cbind(a, b, c, d)
      [,1] [,2] [,3] [,4]
 [1,]    1   11   21   31
 [2,]    2   12   22   32
 [3,]    3   13   23   33
 [4,]    4   14   24   34
 [5,]    5   15   25   35
 [6,]    6   16   26   36
 [7,]    7   17   27   37
 [8,]    8   18   28   38
 [9,]    9   19   29   39
[10,]   10   20   30   40


The use of list(...) in the function allows you to use list based
functions such as do.call() or lapply() against the argument objects
directly without having to deparse and re-parse the character names of
the arguments, which is the approach that Peter used in his response in
the thread you referenced. 

The OP in that thread wanted the argument names as character vectors, as
opposed to the argument objects themselves, which is what you need here.

HTH,

Marc Schwartz




More information about the R-help mailing list