![](/img/trans.png)
[英]Lists or vectors within a column of a data frame, to be able to compare each value and count the matches with R project
[英]Compare two vectors within a data frame with %in% with R
将数据框中的两个向量与 %in% 进行比较
我有以下数据
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,b,c |
b | aa,c,d |
啊 | c,d,e |
d | d,f,g |
我想从这个向量c(“a”,“e”,“g”)中选择包含一个字符的行,指定columna
library(dplyr)
T1 %>% filter(Col1 %in% c("a", "e", "g"))
我回来了
1 aa,b,c
这是正确的,但如果我想比较两个向量,例如:
使用 unlist 和 strsplit,我将每一行的值转换为字符向量,并尝试将其与参考向量进行比较以选择包含任何值的行:
unlist(strsplit(T1$Col2[1],","))
[1] "a" "b" "c"
T1 %>% filter(unlist(strsplit(Col2,",")) %in% c("a", "e", "g"))
它给了我一个错误: filter()
中的错误:! 计算..1 = unlist(strsplit(Col2, ",")) %in% c("a", "e", "g")
问题。 ✖ 输入..1
的大小必须为 4 或 1,而不是 12。运行]8;;rstudio:run:rlang::last_error()rlang::last_error() ]8;;
查看错误发生的位置。
我可以这样做:
T1[grep(c("a|e|g"), T1$Col2),]
1 aa,b,c
2 b aa,c,d
3 aa c,d,e
4 dd,f,g
但这是错误的,第3 aa c,d,e
不应该是,因为它不是a
,它是aa
要单独搜索"a"
,您必须执行以下操作:
T1[grep(c("\\<a\\>"), T1$Col2),]
我认为使用这种形式我最终会犯错误,它将给我更多的安全性来比较向量和向量:
T1 %>% filter(unlist(strsplit(Col2,",")) %in% c("a", "e", "g"))
编辑后的答案
您可以将语法\\b
用于正则表达式单词边界。 该|
用于与类似或操作相邻的边界。 您可以使用以下代码:
T1 <- data.frame( "Col1" = c("a", "b", "aa", "d"), "Col2" = c("a,b,c", "aa,c,d", "c,d,e", "d,f,g") )
library(dplyr)
library(stringr)
T1 %>%
filter(grepl("\\b(a|e|g)\\b", Col2))
#> Col1 Col2
#> 1 a a,b,c
#> 2 aa c,d,e
#> 3 d d,f,g
由reprex 包于 2022-07-16 创建 (v2.0.1)
注意: \\b
用于 R 版本 4.1+,否则使用\b
。
旧答案
它返回所有行,因为您检查 Col2 中是否存在字符串之一,并且您可以看到在第 3 行中,存在“e”,这是字符串之一,这就是它返回第 4 行的原因。您也可以使用str_detect
这个:
library(dplyr)
library(stringr)
T1 <- data.frame( "Col1" = c("a", "b", "aa", "d"), "Col2" = c("a,b,c", "aa,c,d", "c,d,e", "d,f,g") )
vector <- c("a", "e", "g")
T1 %>%
filter(any(str_detect(Col2, paste0(vector, collapse="|"))))
#> Col1 Col2
#> 1 a a,b,c
#> 2 b aa,c,d
#> 3 aa c,d,e
#> 4 d d,f,g
由reprex 包于 2022-07-16 创建 (v2.0.1)
如果要检查字符串是否存在,则在两列中都存在其中之一。 您可以使用以下代码:
library(dplyr)
library(stringr)
T1 <- data.frame( "Col1" = c("a", "b", "aa", "d"), "Col2" = c("a,b,c", "aa,c,d", "c,d,e", "d,f,g") )
vector <- c("a", "e", "g")
T1 %>%
filter(Reduce(`|`, across(all_of(colnames(T1)), ~str_detect(paste0(vector, collapse="|"), .x))))
#> Col1 Col2
#> 1 a a,b,c
由reprex 包于 2022-07-16 创建 (v2.0.1)
您可以实现此目的的另一种方法(使用带有 strsplit 的原始方法)是执行rowwise()
并“求和”逻辑测试。
T1 %>%
rowwise() %>%
filter(sum(unlist(strsplit(Col2,",")) %in% c("a","e","g")) >= 1)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.