6

In improving an rbind method, I'd like to extract the names of the objects passed to it so that I might generate unique IDs from those.

I've tried all.names(match.call()) but that just gives me:

[1] "rbind"         "deparse.level" "..1"           "..2" 

Generic example:

rbind.test <- function(...) {
  dots <- list(...)
  all.names(match.call())
}

t1 <- t2 <- ""
class(t1) <- class(t2) <- "test"
> rbind(t1,t2)
[1] "rbind"         "deparse.level" "..1"           "..2" 

Whereas I'd like to be able to retrieve c("t1","t2").

I'm aware that in general one cannot retrieve the names of objects passed to functions, but it seems like with ... it might be possible, as substitute(...) returns t1 in the above example.

Ari B. Friedman
  • 71,271
  • 35
  • 175
  • 235
  • 2
    possible duplicate of [How to use R's ellipsis feature when writing your own function?](http://stackoverflow.com/questions/3057341/how-to-use-rs-ellipsis-feature-when-writing-your-own-function) – David Robinson Sep 14 '12 at 01:10
  • There are some great answers on the other question. Incidentally, the term for those dots is "ellipsis" (which makes it much easier to Google). – David Robinson Sep 14 '12 at 01:11
  • @DavidRobinson: none of those answers apply because `rbind` and `cbind` use non-standard method dispatch. The answer to this question is actually in the comments of one of the answers to the question you linked to. – Joshua Ulrich Sep 14 '12 at 01:16
  • That's a great question and in fact contained the answer but definitely not a duplicate Q. @mnel just posted the answer right as I found it in there. Thanks for the pointer to that (awesome!) question. – Ari B. Friedman Sep 14 '12 at 01:18
  • @AriB.Friedman, do you want the same output as the `allnams(match.call())` but with `'..1', '..2'` replaced with `'t1','t2'`, or is `'t1','t2'` sufficient? – mnel Sep 14 '12 at 01:22

2 Answers2

13

I picked this one up from Bill Dunlap on the R Help List Serve:

rbind.test <- function(...) {
    sapply(substitute(...()), as.character)
}

I think this gives you what you want.

Tyler Rinker
  • 108,132
  • 65
  • 322
  • 519
  • 1
    Cool. Can you explain the `...()` piece? It's clearly not legit on its own, and I can't imagine what it would be doing inside `substitute`. – Ari B. Friedman Sep 21 '12 at 00:43
  • Uh no I can't Bill Dunlap is a genius I am not. I have no clue why it works but it's his preferred method and he explains the efficiency in a post online. Sorry I don't have the reference for it but it was within the last 4-5 months. – Tyler Rinker Sep 21 '12 at 01:39
  • 3
    Well if you're confused I think it merits a [new question](http://stackoverflow.com/questions/12523548/confused-by). I'm looking forward to having my mind blown. – Ari B. Friedman Sep 21 '12 at 02:41
8

Using the guidance here How to use R's ellipsis feature when writing your own function?

eg substitute(list(...))

and combining with with as.character

rbind.test <- function(...) {
  .x <-  as.list(substitute(list(...)))[-1]
  as.character(.x)
 }

you can also use

rbind.test <- function(...){as.character(match.call(expand.dots = F)$...)}
Community
  • 1
  • 1
mnel
  • 113,303
  • 27
  • 265
  • 254