Search code examples
rtidyeval

How do I capture the argument to a function and apply them as is in another context/environment


I am pretty sure my language is imprecise, but I don't know the correct terms yet. This is what I wanted to achieve:

I have a function abc2. I want to obtain the arguments to them (without evaluating or changing the argument) provided by the user, to use in another function. E.g.

abc2 <- function(...) {
 # what do I have to do here?
}

adf = data.frame(a = 1:3, b = 1:3)
bdf = data.frame(a = 11:13, b = 11:33)

such that calling abc2(a) is the same as calling

dplyr::select(adf, a)
dplyr::select(bdf, a)

and that calling abc2("a") is the same as calling

dplyr::select(adf, "a")
dplyr::select(bdf, "a")

Basically, I want to transplant the ... from abc2 and apply them without any change from how the user has input it and apply elsewhere.

Base R and tidyeval explanation welcome! I am trying to read up on quo and enquo but I can't seem to get my head around it.


Solution

  • 1) base R Pass ... on. Either "a" or just a can be used. The passing mechanism here uses only base R. The dplyr is only so that we can use select.

    library(dplyr)
    
    adf = data.frame(a = 1:3, b = 1:3)
    bdf = data.frame(a = 11:13, b = 21:23)
    
    abc2 <- function(...) {
      print(select(adf, ...))
      print(select(bdf, ...))
    }
    
    # or: abc2(a)
    abc2("a")
    

    giving:

      a
    1 1
    2 2
    3 3
       a
    1 11
    2 12
    3 13
    

    2) rlang This also works but this time we use rlang's enquos and !!! with tidyeval all of which is pulled in by dplyr.

    abc2a <- function(...) {
      dots <- enquos(...)
      print(select(adf, !!!dots))
      print(select(bdf, !!!dots))
    }
    abc2(a)