在函数中获取过滤器以进行整洁的评估

mat*_*sho 3 r dplyr rlang

我正在尝试使用 dplyr 根据动态变量进行过滤。

我发现要使过滤器正常工作,我需要将变量名称括在括号中。但是,如果我将其编程为一个函数,它就无法正常工作。

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")
Run Code Online (Sandbox Code Playgroud)

我想学习为自己找到这些关于 dplyr 的问题类型的答案,所以请随时向我推荐编程小插图的相关部分

Psi*_*dom 5

如果您的函数接受列名作为字符,则无需引用它,另一方面,您需要将其转换为符号并立即在函数中filter使用UQ!!语法对它们进行求值nse

testfun <- function(test_df, filt_var){
    test_df %>%
        dplyr::filter((!!rlang::sym(filt_var)) == 5)
}

testfun(df_ex, "a")
#  a  b
#1 5 15
Run Code Online (Sandbox Code Playgroud)

如果您想键入不带引号的列名称,那么您需要enquo

接受一个引用函数参数的符号,引用提供给该参数的 R 代码,捕获调用该函数的环境(以及键入 R 代码的位置),并将它们捆绑在一个 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
Run Code Online (Sandbox Code Playgroud)