R语言:如何在dplyr的filter中用向量元素作为变量筛选数据?
在dplyr的filter中用向量元素作为筛选变量的解决方法
这个问题我日常用dplyr时也碰到过,核心是tidyverse的非标准求值(NSE)机制在起作用:你直接写cname[2] == 1的时候,R会把cname[2]当成字符串"b"处理,相当于判断"b" == 1——这显然永远是FALSE,所以根本筛选不到数据。要让dplyr识别出你是想引用数据框里的列,需要用tidy eval语法明确告诉它「这不是普通字符串,是列名」。
下面是两种简单好用的解决方法:
方法1:使用.data代词(官方推荐)
这是tidyverse官方主推的方式,直观易懂,不需要额外加载包:
cname <- c("a","b","c") test1 <- table1 %>% filter(a %in% c("c1")) %>% filter(.data[[cname[2]]] == 1)
.data是一个特殊代词,代表当前管道中的数据框,用[[ ]]传入列名字符串,就能精准定位到对应的列。
方法2:使用rlang的符号转义
如果习惯用tidy eval的底层语法,可以把字符串转换成R能识别的变量符号,再用!!(bang-bang)强制求值:
# rlang已包含在tidyverse中,无需单独加载 cname <- c("a","b","c") test1 <- table1 %>% filter(a %in% c("c1")) %>% filter(!!sym(cname[2]) == 1)
sym()会把字符串"b"转换成变量符号b,!!则告诉dplyr:「别把这个符号当普通代码,去求值它对应的列」。
验证结果
运行上面任意一种方法后,test1和你最初的test结果完全一致:
> test a b c 1 c1 1 5 2 c1 1 8 > test1 a b c 1 c1 1 5 2 c1 1 8
内容的提问来源于stack exchange,提问作者Zheng Liu
相关产品推荐
相关产品推荐

