Skip to content

Instantly share code, notes, and snippets.

@HorridTom
Last active September 16, 2021 11:17
Show Gist options
  • Save HorridTom/125b6d38a2383ec28660b886504fc8d0 to your computer and use it in GitHub Desktop.
Save HorridTom/125b6d38a2383ec28660b886504fc8d0 to your computer and use it in GitHub Desktop.
Tidy evaluation with user-specified column names
# Passing user-specified column names to tidyverse functions inside your own functions
# Based on: https://dplyr.tidyverse.org/articles/programming.html
library(tidyverse)
str(mtcars)
# How you might think you write a function that takes a column name as argument
# and uses tidyverse functions to do something based on that column name...
my_first_group_summarise_fn <- function(df, col_name) {
df_grouped_summarised <- df %>%
group_by(col_name) %>%
summarise(freq = n())
return(df_grouped_summarised)
}
# But this doesn't work...
my_first_group_summarise_fn(df = mtcars, col_name = "gear") # pass as string (doesn't work)
my_first_group_summarise_fn(df = mtcars, col_name = gear) # pass using tidy evaluation (doesn't work)
# group_by is looking for a column called col_name
# so instead... if you want to pass the column name as a string...
my_second_group_summarise_fn <- function(df, col_name) {
df_grouped_summarised <- df %>%
group_by(.data[[col_name]]) %>%
summarise(freq = n())
return(df_grouped_summarised)
}
my_second_group_summarise_fn(df = mtcars, col_name = "gear") # pass as string (works)
my_second_group_summarise_fn(df = mtcars, col_name = gear) # pass using tidy evaluation (doesn't work)
# And if you want to be able to use tidyverse semantics for your own function...
my_third_group_summarise_fn <- function(df, col_name) {
df_grouped_summarised <- df %>%
group_by({{ col_name }}) %>%
summarise(freq = n())
return(df_grouped_summarised)
}
my_third_group_summarise_fn(df = mtcars, col_name = "gear") # pass as string (doesn't work)
my_third_group_summarise_fn(df = mtcars, col_name = gear) # pass using tidy evaluation (works)
# Some more operations
my_fourth_group_summarise_fn <- function(df, col_name) {
print(class(df %>% pull({{ col_name }})))
df <- df %>% mutate("{{ col_name }}" := {{ col_name }} + 1)
df_grouped_summarised <- df %>%
group_by({{ col_name }}) %>%
summarise(freq = n())
df_grouped_summarised2 <- df_grouped_summarised %>%
rename(passed_col = {{ col_name }})
colplot <- ggplot(df_grouped_summarised, aes(x = {{ col_name }}, y = freq)) +
geom_bar(stat = "identity")
return(colplot)
}
my_fourth_group_summarise_fn(df = mtcars, col_name = "gear") # pass as string (doesn't work)
my_fourth_group_summarise_fn(df = mtcars, col_name = gear) # pass using tidy evaluation (works)
my_fourth_group_summarise_fn(df = mtcars, col_name = cyl) # pass using tidy evaluation (works)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment