darckeen
darckeen

Reputation: 960

using substitute to get argument name with

I'm trying to get the names of arguments in the global environment within a function. I know I can use substitute to get the name of named arguments, but I would like to be able to do the same thing with ... arguments. I kinda got it to work for the first element of ... but can't figure out how to do it for the rest of the elements. Any idea how to get this working as intended.

foo <- function(a,...)
{
    print(substitute(a))
    print(eval(enquote(substitute(...))))
    print(sapply(list(...),function(x) eval(enquote(substitute(x)),env=.GlobalEnv)))
}

x <- 1
y <- 2
z <- 3
foo(x,y,z)

x
y
[[1]]
X[[1L]]

[[2]]
X[[2L]]

Upvotes: 33

Views: 10883

Answers (2)

Marek
Marek

Reputation: 50704

I would go with

foo <- function(a, ...) {
print( n <- sapply(as.list(substitute(list(...)))[-1L], deparse) )
    n
}

Then

foo(x,y,z)
# [1] "y" "z"

Related question was previously on StackOverflow: How to use R's ellipsis feature when writing your own function? Worth reading.


Second solution, using match.call

foo <- function(a, ...) {
    sapply(match.call(expand.dots=TRUE)[-1], deparse)
}

Upvotes: 23

Gavin Simpson
Gavin Simpson

Reputation: 174813

The canonical idiom here is deparse(substitute(foo)), but the ... needs slightly different processing. Here is a modification that does what you want:

foo <- function(a, ...) {
    arg <- deparse(substitute(a))
    dots <- substitute(list(...))[-1]
    c(arg, sapply(dots, deparse))
}

x <- 1
y <- 2
z <- 3

> foo(x,y,z)
[1] "x" "y" "z"

Upvotes: 64

Related Questions