簡體   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