如何在自定义函数中向filter()传递未加引号的参数
解决未加引号参数过滤数据集的问题
错误原因
你之前的代码里,{{var_to_filter_on}} 的作用是引用变量名(比如列名)的非标准求值,而非把裸写的virginica转换成字符串值。当调用filter_function(virginica)时,R会去查找名为virginica的对象,但这个对象并不存在,因此触发报错。
解决方案
要实现传入未加引号的取值(支持单个或多个),可以借助rlang包的工具把裸参数转换成字符向量,再用%in%完成过滤。
方法1:支持传入多个裸参数(推荐)
这种方式用户可直接传入多个未加引号的取值,无需用c()包裹:
library(dplyr) library(rlang) library(purrr) filter_function <- function(...){ # 将所有传入的裸参数转换为字符向量 filter_values <- map_chr(ensyms(...), as_label) test_data <- iris %>% filter(Species %in% filter_values) print(test_data) } # 调用示例 filter_function(virginica) # 单个取值 filter_function(setosa, versicolor) # 多个取值
方法2:支持传入c()包裹的裸参数
如果用户习惯用c()传入多个取值,可以解析表达式提取其中的符号并转换为字符:
library(dplyr) library(rlang) library(purrr) filter_function <- function(var_to_filter_on){ # 捕获传入的表达式 filter_expr <- enquo(var_to_filter_on) # 提取表达式中的所有符号并转为字符 filter_values <- map_chr(expr_get(filter_expr), as_label) test_data <- iris %>% filter(Species %in% filter_values) print(test_data) } # 调用示例 filter_function(c(virginica, setosa)) filter_function(versicolor)
原理说明
ensyms(...):把每个传入的裸参数转换为符号对象(比如把virginica变成sym("virginica"))as_label():把符号对象转换成对应的字符串(sym("virginica")→"virginica")- 最终得到字符向量后,就能用
%in%匹配Species列中的取值了
内容的提问来源于stack exchange,提问作者Gin_Salmon
相关产品推荐
相关产品推荐

