Search code examples
rdplyrtidyeval

Evaluate function argument as string within dplyr custom function


I am writing a custom function that outputs the mean and sd of a field. I would like the .field argument to be evaluated in a tidyeval manner at some states and as a string at another stage. How can I evaluate the .field argument as a string?

library(dplyr)
library(tidyr)

mean_sd <- function(.data, .field){
    .data %>% 
    summarise(
        mean = mean({{.field}}), 
        sd = sd({{.field}})
    ) %>% 
    pivot_longer(
        everything(),
        names_to = "stat",
        values_to = '.field' # I'd like this to print the value of .field
        ) %>% 
    mutate(across(is.numeric, ~round(.x, 2)))
}

mean_sd(mtcars, mpg)

enter image description here


Solution

  • Besides the more elegant rlang::englue another option would be to use as_label(enquo(x)):

    library(dplyr, warn.conflicts = FALSE)
    library(tidyr)
    
    mean_sd <- function(.data, .field) {
      .data %>%
        summarise(
          mean = mean({{ .field }}),
          sd = sd({{ .field }})
        ) %>%
        pivot_longer(
          everything(),
          names_to = "stat",
          values_to = as_label(enquo(.field))
        ) %>%
        mutate(across(where(is.numeric), ~ round(.x, 2)))
    }
    
    mean_sd(mtcars, mpg)
    #> # A tibble: 2 × 2
    #>   stat    mpg
    #>   <chr> <dbl>
    #> 1 mean  20.1 
    #> 2 sd     6.03