character vector for name of a passed variable in new dplyr programming syntax

How does one recover a character vector for the name of a variable passed to a function that is meant to work with the "new" dplyr programming syntax? The specific problem I am trying to solve is passing to by in a join step inside such a function. Here is a grossly simplified example that I can't make work:

myfun <- function(df1, df2, byvar){
  inner_join(df1, df2, by = byvar)
}

Since by is expecting a character vector, but byvar is an expression (a quosure? I can't keep track) I'm guessing I need to wrap byvar in something, but I can't figure out what. The embrace operator doesn't do it, nor does wrapping the embrace operator in a pair of quotes.

Thanks in advance for any suggestions.

I don't think you need to use quosures for the join. You can just pass a character string for the join variable(s). For example:

library(tidyverse)

# Create two data frames to join
d = mtcars %>% rownames_to_column() %>% slice(1:5)
d1 = d[ , 1:3]
d2 = d[ , c(1, 4:5)]

d1
#>             rowname  mpg cyl
#> 1         Mazda RX4 21.0   6
#> 2     Mazda RX4 Wag 21.0   6
#> 3        Datsun 710 22.8   4
#> 4    Hornet 4 Drive 21.4   6
#> 5 Hornet Sportabout 18.7   8
d2
#>             rowname disp  hp
#> 1         Mazda RX4  160 110
#> 2     Mazda RX4 Wag  160 110
#> 3        Datsun 710  108  93
#> 4    Hornet 4 Drive  258 110
#> 5 Hornet Sportabout  360 175
# Join function
myfun <- function(df1, df2, byvar){
  inner_join(df1, df2, by = byvar)
}

# Pass join column as a string
myfun(d1, d2, "rowname")
#>             rowname  mpg cyl disp  hp
#> 1         Mazda RX4 21.0   6  160 110
#> 2     Mazda RX4 Wag 21.0   6  160 110
#> 3        Datsun 710 22.8   4  108  93
#> 4    Hornet 4 Drive 21.4   6  258 110
#> 5 Hornet Sportabout 18.7   8  360 175

I don't think it's necessary to do the following (though maybe there are cases where we would want to join by a column dynamically created and passed from one function to another), but if you wanted to pass the bare column name, you could convert it to a string inside the function. If by the "embrace" operator you mean {{x}}, this doesn't work because this operator both quotes and unquotes. To get a string, we want to just quote the column name and then use as_label to convert the quosure to a character string. For example:

myfun2 <- function(df1, df2, byvar){
  
  # Show the we're converting byvar to a character string
  print(as_label(enquo(byvar)))
  
  inner_join(df1, df2, by = as_label(enquo(byvar)))
}

myfun2(d1, d2, rowname)
#> [1] "rowname"
#>             rowname  mpg cyl disp  hp
#> 1         Mazda RX4 21.0   6  160 110
#> 2     Mazda RX4 Wag 21.0   6  160 110
#> 3        Datsun 710 22.8   4  108  93
#> 4    Hornet 4 Drive 21.4   6  258 110
#> 5 Hornet Sportabout 18.7   8  360 175
1 Like

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

I swear I tried some combination with as_label and enquo but I must have missed this one. that totally works, thanks.

also, the reason why I needed the myfun2 syntax is that I'm using byvar other places in the function inside the embrace operator.