如何在R语言中用%in%比较数据框内的两个向量?
问题:筛选包含指定元素的行(基于dplyr的向量匹配方法)
数据集
首先定义数据集:
T1 <- data.frame( "Col1" = c("a", "b", "aa", "d"), "Col2" = c("a,b,c", "aa,c,d", "c,d,e", "d,f,g") )
对应的表格:
| Col1 | Col2 |
|---|---|
| a | a,b,c |
| b | aa,c,d |
| aa | c,d,e |
| d | d,f,g |
筛选Col1的正确方法
使用dplyr筛选Col1中属于c("a", "e", "g")的行,代码和结果均正确:
library(dplyr) T1 %>% filter(Col1 %in% c("a", "e", "g"))
返回结果:
Col1 Col2 1 a a,b,c
处理Col2时的错误尝试
尝试将Col2的每行字符串拆分为字符向量后与目标向量匹配,但直接使用unlist(strsplit(...))会报错:
# 单独拆分一行的结果符合预期 unlist(strsplit(T1$Col2[1],","))
输出:
[1] "a" "b" "c"
执行筛选代码时出现错误:
T1 %>% filter(unlist(strsplit(Col2,",")) %in% c("a", "e", "g"))
错误信息:
Error in `filter()`: ! Problem while computing `..1 = unlist(strsplit(Col2, ",")) %in% c("a", "e", "g")`. ✖ Input `..1` must be of size 4 or 1, not size 12. Run `rlang::last_error()` to see where the error occurred.
grep方法的局限性
用grep尝试匹配时,会错误匹配包含目标元素的子串(比如aa中的a):
T1[grep(c("a|e|g"), T1$Col2),]
返回错误结果(误包含第2、3行):
Col1 Col2 1 a a,b,c 2 b aa,c,d 3 aa c,d,e 4 d d,f,g
虽然可以用边界匹配修正:
T1[grep(c("\\<a\\>"), T1$Col2),]
但这种正则方式容易出错,更倾向于用向量与向量直接对比的方式实现准确筛选。
正确的dplyr解决方案
方法1:rowwise() + any()
对每行单独处理,检查拆分后的向量是否包含目标元素中的任意一个:
T1 %>% rowwise() %>% filter(any(strsplit(Col2, ",")[[1]] %in% c("a", "e", "g"))) %>% ungroup()
返回正确结果:
# A tibble: 3 × 2 Col1 Col2 <chr> <chr> 1 a a,b,c 2 aa c,d,e 3 d d,f,g
方法2:purrr::map_lgl()
结合purrr包的映射函数,生成每行的逻辑判断向量:
library(purrr) T1 %>% filter(map_lgl(strsplit(Col2, ","), ~ any(.x %in% c("a", "e", "g"))))
可得到相同的正确结果。
方法3:拆分后去重筛选(tidyr)
用tidyr的separate_rows()将Col2拆分为多行,筛选后再去重:
library(tidyr) T1 %>% separate_rows(Col2, sep = ",") %>% filter(Col2 %in% c("a", "e", "g")) %>% distinct(Col1, .keep_all = TRUE)
结果一致:
Col1 Col2 1 a a 2 aa e 3 d g
内容的提问来源于stack exchange,提问作者Laura MS
相关产品推荐
相关产品推荐

