change names in dots to characters

Viewed 111

I have a function like this one:

my_fun <- function(...,x,y){
  list(...)
}

I want to be able to feed variable names OR strings to the ellipsis and convert all to character before returning. In my real case I will call a custom function through do.call(custom_fun,list(...)).

Expected output

What I'm asking here is a function my_fun2 that would have the following behavior :

my_fun2 <- function(...,x,y){
  MAGIC(list(...))
}

identical(my_fun("a",foo= "b == 3",c("c","d"),bar=c("e","f"),c("g","h")),
          my_fun2("a",foo= b == 3,c("c","d"),bar = c("e",f),c(g,h)))

should be TRUE and both terms return:

# [[1]]
# [1] "a"
# 
# $foo
# [1] "b == 3"
# 
# [[3]]
# [1] "c" "d"
# 
# $bar
# [1] "e" "f"
# 
# [[5]]
# [1] "g" "h"

What I tried...

my_fun2 <- function(...,x,y){
 lapply(pryr::dots(...),as.character)
}

my_fun2("a",b == 3,c("c","d"),c("e",f),c(g,h))
# [[1]]
# [1] "a"
# 
# [[2]]
# [1] "==" "b"  "3" 
# 
# [[3]]
# [1] "c" "c" "d"
# 
# [[4]]
# [1] "c" "e" "f"
# 
# [[5]]
# [1] "c" "g" "h"

Notes

I don't have a good understanding of expressions, quotes, quosures, calls, names.. so I'll appreciate explanations relevant to the case.

I'm fine with solutions using either (or both!) base (substitute, quote etc) and dplyr answers (enquo, quosetc)

1 Answers

I'm not proud but this had to be done...

library(dplyr)
library(purrr)
library(pryr)
my_fun2 <- function(...,x,y){
  dots0 <- as.character(substitute(alist(...)))[-1]
  vectors <- substr(dots0,1,2) == "c("
  dotsv <- dots0[vectors] %>%
    gsub("\"","",.)    %>% 
    gsub("(","('",.,fixed=TRUE)   %>% 
    gsub(", ","', '",.,fixed=TRUE)  %>%
    gsub(")","')",.,fixed=TRUE)  %>%
    map(~eval(parse(text=.x)))
  setNames(c(as.list(dots0[!vectors]),dotsv),names(pryr::dots(...)))
}

identical(my_fun2("a",foo= "b == 3",c("c","d"),bar = c("e","f"),c("g","h")),
my_fun2("a",foo= b == 3,c("c","d"),bar = c("e",f),c(g,h)))
# [1] TRUE

# [[1]]
# [1] "a"
# 
# $foo
# [1] "b == 3"
# 
# [[3]]
# [1] "c" "d"
# 
# $bar
# [1] "e" "f"
# 
# [[5]]
# [1] "g" "h"
Related