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

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.

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