How to provide an unquoted variable name as a function argument

Hello experts. I think this is a somewhat advanced topic. Let me start with an example code.

test_data = tibble(a = sample(c("group 1","group 2"), 100, replace=T), 
                   b = rnorm(100))

test_fun = function(data, group, value) {
  data %>% group_by(group) %>% summarize(mean=mean(value))
}

test_fun(test_data, a, b)
#Error: Must group by variables found in `.data`.
#* Column `group` is not found.

test_fun(test_data, quote(a), quote(b))
#Error: Must group by variables found in `.data`.
#* Column `group` is not found.

As shown in the example, I want to make a function that takes a tibble and unquoted variable names as arguments and do some data transformation with tidyverse workflow. I expected quote(variable) would work, but it didn't (I don't quite understand why). How can I make this function work?

1 Like

See https://www.tidyverse.org/blog/2019/06/rlang-0-4-0/#a-simpler-interpolation-pattern-with and https://dplyr.tidyverse.org/articles/programming.html

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
test_data = tibble(a = sample(c("group 1","group 2"), 100, replace=T), 
                   b = rnorm(100))

test_fun = function(data, group, value) {
  data %>% group_by({{ group}} ) %>% summarize(mean=mean({{ value }}))
}

test_fun(test_data, a, b)
#> `summarise()` ungrouping output (override with `.groups` argument)
#> # A tibble: 2 x 2
#>   a         mean
#>   <chr>    <dbl>
#> 1 group 1 0.0526
#> 2 group 2 0.241
3 Likes

Actually I've come up with another solution, which I believe can be applied more generally.

test_data = tibble(a = sample(c("group 1","group 2"), 100, replace=T), 
                   b = rnorm(100))

test_fun = function(data, group, value) {
  substitute(data %>% group_by(group) %>% summarize(mean=mean(value))) %>% eval
}

test_fun(test_data, a, b)
## A tibble: 2 x 2
#a          mean
#<chr>     <dbl>
#1 group 1 -0.169 
#2 group 2 -0.0143

Read https://dplyr.tidyverse.org/articles/programming.html#one-or-more-user-supplied-expressions
Using {{ }} is easier to read, write and it is the standard in the tidyverse.

1 Like

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