Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting filter within a function to work with tidy evaluation

Tags:

r

dplyr

rlang

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

like image 960
matsuo_basho Avatar asked Apr 11 '26 03:04

matsuo_basho


1 Answers

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
like image 113
Psidom Avatar answered Apr 13 '26 22:04

Psidom



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!