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

From: Marc Schwartz (via MN) <mschwartz_at_mn.rr.com>
Date: Wed 20 Jul 2005 - 02:00:17 EST

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



R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html Received on Wed Jul 20 02:05:43 2005

This archive was generated by hypermail 2.1.8 : Fri 03 Mar 2006 - 03:33:48 EST