2

Possible Duplicate:
How to use R's ellipsis feature when writing your own function?

I am wondering how R interprets ... arguments?

For instance consider the makeContrasts(..., contrasts=NULL, levels) of package limma. You can run:

 > require(limma)
 > makeContrasts(a + b, b+c, levels=letters[1:3])

       Contrasts
 Levels a + b b + c
      a     1     0
      b     1     1
      c     0     1

and it interprets the parameters a + b, b+c without a, b and c being already defined as R objects.

I tried to make a similar function:

foo = function(...) {
    print(typeof(...))
}

> foo(a + b) 
Error in typeof(...) : object 'a' not found

So I am really confused what type of object is really passed to makeContrasts? And is there anyway to modify this object?

Community
  • 1
  • 1
Ali
  • 9,440
  • 12
  • 62
  • 92
  • Search for `[r] ellipsis` on SO and you will find many questions from which you will be able to find your answers. Also the [r-intro](http://cran.r-project.org/doc/manuals/R-intro.html#The-three-dots-argument) and other docs have all this information\ – mnel Oct 04 '12 at 23:30
  • Also, if you want your function to process arguments like `limma::makeContrasts`, type `limma::makeContrasts` to have a look 'inside' it. – Josh O'Brien Oct 04 '12 at 23:34
  • Thanks, but I have already done your recommended ideas. My question of what is the type of `a + b` was not answered anywhere. – Ali Oct 04 '12 at 23:48
  • IF you read the R manuals it is clear Try [here](http://cran.r-project.org/doc/manuals/R-lang.html). (perhaps the first link did not have everything you were looking for, the `R-Lang` is detailed and easy to read – mnel Oct 04 '12 at 23:58
  • 3
    That's hard to answer because `a + b` is many things. It is (at least): (1) a supplied (but unmatched) argument to the function call `makeContrasts(a+b)`; (2) the expression slot of one of the promise objects stored in the `...` special object; (3) a "call" or "language" object, such as is returned by typing `quote(a + b)` – Josh O'Brien Oct 04 '12 at 23:59
  • 1
    Thanks Josh. Better to post it as an answer such that I can mark this question answered. – Ali Oct 05 '12 at 00:06

1 Answers1

3

It is a "language expression". When you pass it to typeof the interpreter attempts to find a name to match to a and fails, so it generates an error. If you processed it with functions that handle items of type "language" you get a (more) sensible result.

As it is take a look at this:

> a="aa"
> typeof(a+b)
Error in typeof(a + b) : object 'b' not found
> b="bb"
> typeof(a+b)
Error in a + b : non-numeric argument to binary operator

We fixed the non-existence of a and then the R interpreter wanted to be able to find b and then it realized that + was not being given numeric arguments. So the interpreter was attempting to evaluate the expression a+b in it usual fashion and reporting problems as it encountered them. In my response to your at that time incomplete question about mimicking makeContrasts I offered a mechanism for seeing what the R interpreter was doing with that expression:

 foo = function(...) {
      e <- substitute(...)
      e[[1]]
 }

  foo(a + b)
# `+`

When you want to examine the nature of something that is not a named element in the workspace with typeof which is otherwise expecting to get a character value, you need to quote it:

> typeof(quote(a+b))
[1] "language"
> typeof(quote("a"))
[1] "character"
IRTFM
  • 258,963
  • 21
  • 364
  • 487