1

I have a simple problem with non-standard evaluation: passing a variable name as an argument into a function.

As a reproducible example, here's a simple thing: taking the mean of one variable, mpg from the mtcars dataset. My end goal is to have a function where I can input the dataset and the variable, and get the mean.

So without a function:

library(tidyverse)
mtcars %>% summarise(mean = mean(mpg))

#>       mean
#> 1 20.09062

I've tried to use get() for non-standard evaluation, but I'm getting errors:

library(tidyverse)
summary_stats <- function(variable, dataframe){
  dataframe %>% summarise(mean = get(variable))
}

summary_stats(mpg, mtcars)

#> Error: Problem with `summarise()` input `mean`.
#> x invalid first argument
#> ℹ Input `mean` is `get(variable)`.

Created on 2020-09-19 by the reprex package (v0.3.0)

Edit:

I also had one additional follow-up question.

I also need the variable argument as a char string, I tried the code below, but I'm still missing how to do that:

library(tidyverse)
summary_stats <- function(variable, dataframe){
  dataframe %>% summarise(mean = mean({{variable}}))
  print(as.character({{variable}}))
}

summary_stats(disp, mtcars)
#> Error in print(as.character({: object 'disp' not found

Created on 2020-09-19 by the reprex package (v0.3.0)

Jeremy K.
  • 1,710
  • 14
  • 35
  • 1
    Here's the dplyr vignette that you'll find helpful for stuff like tidyeval => https://cran.r-project.org/web/packages/dplyr/vignettes/programming.html – theairbend3r Sep 19 '20 at 03:56
  • For anyone reading this question in the future, @theairbend3r 's link is exactly the sort of documentation that steps through the answer, and is just what I was looking for. – Jeremy K. Sep 19 '20 at 03:59

1 Answers1

1

You could use the curly-curly ({{}}) operator to pass column name as unquoted variable.

To get variables passed as character value we can use deparse, substitute.

library(dplyr)
library(rlang)

summary_stats <- function(variable, dataframe){
  print(deparse(substitute(variable)))
  dataframe %>% summarise(mean = mean({{variable}}))
}
#[1] "mpg"

#      mean
#1 20.09062
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213