How to get names of dot-dot-dot arguments in R [duplicate]
Asked Answered
L

4

7

How obtaining a characters vector containing the name of the dot-dot-dot arguments passed to a function e.g.:

test<-function(x,y,...)
{
    varnames=deparseName(substitute(list(...)))
    # deparseName does not exist, this is what I want !
    # so that I could *for example* call:

    for(elt in varnames)
       {print(varnames);}
}

v1=11
v2=10
test(12,12,v1,v2)

## would print 
#v1
#v2
Lentic answered 10/7, 2018 at 7:21 Comment(6)
check out match.callOyler
just print(list(...)) inside the function should do. See https://mcmap.net/q/1474834/-scope-of-dot-dot-dot-argumentsVampirism
@Cath. print(list(...)) does not give the expected output. It prints the content of variables.Lentic
This link might be interesting for youWampler
I guess print(names(list(...))) will do what you wantVampirism
To be clear, despite the title this question is not asking for argument names, but names passed as arguments, e.g. for y but not x in f(x = 10, y).Hardened
V
12

You can use deparse and substitute to get what you want (see also this Q&A):

test<-function(x, y, ...)
{
    varnames=lapply(substitute(list(...))[-1], deparse)
    lapply(varnames, print)
    return(invisible())
}

test(12,12,v1,v2)
#[1] "v1"
#[1] "v2"
Vampirism answered 10/7, 2018 at 8:7 Comment(0)
L
15

Try this:

test<-function(x,y,...)
{
  mc <- match.call(expand.dots = FALSE)
  mc$...
}

v1=11
v2=10
test(12,12,v1,v2)
[[1]]
v1

[[2]]
v2
Latonia answered 10/7, 2018 at 7:50 Comment(0)
V
12

You can use deparse and substitute to get what you want (see also this Q&A):

test<-function(x, y, ...)
{
    varnames=lapply(substitute(list(...))[-1], deparse)
    lapply(varnames, print)
    return(invisible())
}

test(12,12,v1,v2)
#[1] "v1"
#[1] "v2"
Vampirism answered 10/7, 2018 at 8:7 Comment(0)
H
6

To extend the other answers a bit, if you just want the parameters passed to ... that are names, you can use is.name to subset the unevaluated dots before deparsing them to strings:

v1 <- 12
v2 <- 47
v3 <- "foo"

test <- function(x, y, ...){
    dots <- match.call(expand.dots = FALSE)$...
    dots <- dots[sapply(dots, is.name)]
    sapply(dots, deparse)
}

test(2, y = v1, z = v2, 1, v3)
#>    z      
#> "v2" "v3"
Hardened answered 10/7, 2018 at 15:4 Comment(0)
A
3

So, here's how match.call works :

  • match.call()[[1]] returns the name of the function

Then all the args are passed, so match.call()[[2]] and match.call()[[3]] return the 1 and 2nd param, with the value if there is no name (as here) :

test<-function(x,y,...) {
  list(
    match.call()[[1]],
    match.call()[[2]], 
    match.call()[[3]],
    match.call()[[4]],
    match.call()[[5]]
    )
}

v1=11
v2=10
test(12,12,v1,v2)
[[1]]
test

[[2]]
[1] 12

[[3]]
[1] 12

[[4]]
v1

[[5]]
v2

So if you need, here, the dots, you can do :

test<-function(x,y,...) {
  mc <- match.call()
  res <- c()
  for (i in 4:length(mc)){
    res <- c(res, mc[[i]])
  }
  res
}
Atingle answered 10/7, 2018 at 7:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.