Referencing new nonstandard evaluation variables in dplyr

dplyr

#1

If I use the code given in the dplyr vignette,

my_mutate <- function(df, expr) {
  expr <- enquo(expr)
  mean_name <- paste0("mean_", quo_name(expr))
  sum_name <- paste0("sum_", quo_name(expr))

  mutate(df,
    !!mean_name := mean(!!expr),
    !!sum_name := sum(!!expr)
  )
}

What I want to do is write a function that in my unenlightened mind should work like this:

my_mutate <- function(df, expr) {
  expr <- enquo(expr)
  mean_name <- paste0("mean_", quo_name(expr))
  sum_name <- paste0("sum_", quo_name(expr))

mutate(df,
    !!mean_name := mean(!!expr),
    !!sum_name := sum(!!expr),
greater_5 = case_when( !!sum_name >5 ~"yes",
           T ~ "no"

  ) 
}

#3

Using !! sum_name references the name you've created, not the value associated with it. In this case, you could use the expression associated with the name to get the value:

library(tidyverse)

df <- tibble(
  g1 = c(1, 1, 2, 2, 2),
  g2 = c(1, 2, 1, 2, 1),
  a = sample(5),
  b = sample(5)
)

my_mutate <- function(df, expr) {
  expr <- enquo(expr)
  mean_name <- paste0("mean_", quo_name(expr))
  sum_name <- paste0("sum_", quo_name(expr))

  mutate(df,
    !!mean_name := mean(!!expr),
    !!sum_name := sum(!!expr),
    greater_5 = case_when(
      sum(!!expr) > 5 ~ "yes",
      TRUE ~ "no"
    ),
    greater_40 = case_when(
      sum(!!expr) > 40 ~ "yes",
      TRUE ~ "no"
    )
  )
}

my_mutate(df, a)
#> # A tibble: 5 x 8
#>      g1    g2     a     b mean_a sum_a greater_5 greater_40
#>   <dbl> <dbl> <int> <int>  <dbl> <int> <chr>     <chr>     
#> 1     1     1     2     3      3    15 yes       no        
#> 2     1     2     4     2      3    15 yes       no        
#> 3     2     1     3     4      3    15 yes       no        
#> 4     2     2     1     1      3    15 yes       no        
#> 5     2     1     5     5      3    15 yes       no

Created on 2019-02-08 by the reprex package (v0.2.1)


#4

Or maybe !!sym(sum_name) > 5 so the sum is not computed several times ? (Cannot test, i'm on my phone :)).