I'm trying to use dplyr to filter based on a dynamic variable.
I've figured out that to get filter to work, I need to enclose the variable name in parentheses. However, if I program this into a fuction, it does not work properly.
df_ex <- data.frame(a = 1:10, b = 11:20)
param <- quo(a)
# returns df_ex with column a, only, as expected
df_ex %>%
dplyr::select(!!param)
# returns expected df
df_ex %>%
dplyr::filter((!!param)==5)
# Now for the function
testfun <- function(test_df, filt_var){
filt_var_mod <- quo(filt_var)
test_df %>%
dplyr::filter((!!filt_var_mod)==5)
}
# returns empty df, not as expected
testfun(df_ex, "a")
I would like to learn to find the answers to these questions types of questions about dplyr for myself, so please feel free to refer me to the relevant part of the programming vignette
If your function accepts column name as character, then there is no need to quote it, on the other hand you need to convert it to a symbol and evaluate them in the filter function immediately with UQ or !! in the nse syntax:
testfun <- function(test_df, filt_var){
test_df %>%
dplyr::filter((!!rlang::sym(filt_var)) == 5)
}
testfun(df_ex, "a")
# a b
#1 5 15
If you want to type the column names without quotes, then you need enquo, which
takes a symbol referring to a function argument, quotes the R code that was supplied to this argument, captures the environment where the function was called (and thus where the R code was typed), and bundles them in a quosure.
testfun <- function(test_df, filt_var){
filt_var_mod <- enquo(filt_var)
test_df %>%
dplyr::filter((!!filt_var_mod) == 5)
}
testfun(df_ex, a)
# a b
#1 5 15
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With