Last active
September 16, 2021 11:17
-
-
Save HorridTom/125b6d38a2383ec28660b886504fc8d0 to your computer and use it in GitHub Desktop.
Tidy evaluation with user-specified column names
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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