繁体   English   中英

将数据框中的两个向量与 %in% 与 R 进行比较

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM