Guilherme Salome
Guilherme Salome

Reputation: 2049

List of unquoted names to list of strings

Consider a simple function for converting unquoted names to a list of strings character vector:

fun <- function(...) {
  return(sapply(rlang::ensyms(...), rlang::as_string))
}

> fun(abc, def)
"abc" "def"

Question: How can I write a similar function that takes a list of unquoted names instead of using ellipsis (...)?

foo <- function(x) {
  return(???)
}

> foo(list(abc, def))
"abc" "def"

Edit: The use of rlang::ensyms is relevant, since I want the function to "throw an error when the defused expressions are not simple symbols".

Upvotes: 1

Views: 118

Answers (1)

G. Grothendieck
G. Grothendieck

Reputation: 270298

fun in the question converts its arguments to a character vector, not a list of strings. If you want to convert it to a list of strings then use fun2 below. (See this thread for more info on ...(). Can optionally use match.call()[-1] in its place.)

Now fun3 uses non-standard evaluation accepting an argument which must be of the form list(abc, def) and ends up calling fun2 to process it. If you did want to use fun from the question replace "fun2" with "fun" in fun3.

No packages are used.

Note that it is questionable whether all this is a good idea. Using non-standard evaluation generally gets you into trouble when you don't want to hard code names.

fun2 <- function(...) {
  L <- lapply(substitute(...()), as.character)
  stopifnot(all(lengths(L) == 1))
  L
}
fun2(abc, def) # test

fun3 <- function(x) {
  s <- substitute(x)
  s[[1]] <- as.name("fun2")
  eval(s)   
}
fun3(list(abc, def)) # test

Upvotes: 1

Related Questions