确定向量的哪些元素与第二个向量部分匹配,哪些元素不匹配(在 R 中)

Determine which elements of a vector partially match a second vector, and which elements don't (in R)

我有一个向量 A,它包含一个属列表,我想用它来对第二个向量 B 进行子集化。我已经成功地使用 grepl 从 B 中提取了与 A 中的属部分匹配的任何内容。下面是我所做的一个可重现的例子。

但现在我想获得 A 中哪些属与 B 中的某些属匹配以及哪些属不匹配的列表。 IE。 “匹配”列表将包含 Cortinarius 和 Russula,“不匹配”列表将包含 Laccaria 和 Inocybe。关于如何做到这一点的任何想法?实际上我的向量很长,B中的属名在其他信息中并不都在同一个位置。

# create some dummy vectors
A <- c("Cortinarius","Laccaria","Inocybe","Russula")
B <- c("fafsdf_Cortinarius_sdfsdf","sdfsdf_Russula_sdfsdf_fdf","Tomentella_sdfsdf","sdfas_Sebacina","sdfsf_Clavulina_sdfdsf")

# extract the elements of B that have a partial match to anything in A.
new.B <- B[grepl(paste(A,collapse="|"), B)]

# But now how do I tell which elements of A were present in B, and which ones were not?

我们可以使用 lapplysapply 循环模式,然后得到一个命名输出

out <- setNames(lapply(A, function(x) grep(x, B, value = TRUE)), A)

然后,更容易检查返回空元素的那些

> out[lengths(out) > 0]
$Cortinarius
[1] "fafsdf_Cortinarius_sdfsdf"

$Russula
[1] "sdfsdf_Russula_sdfsdf_fdf"

> out[lengths(out) == 0]
$Laccaria
character(0)

$Inocybe
character(0)

并得到 names

> names(out[lengths(out) > 0])
[1] "Cortinarius" "Russula"    
> names(out[lengths(out) == 0])
[1] "Laccaria" "Inocybe" 

您可以将 sapplygrepl 结合使用来检查 A 的每个值是否与 B 的任何值相匹配。

sapply(A, grepl, B)

#     Cortinarius Laccaria Inocybe Russula
#[1,]        TRUE    FALSE   FALSE   FALSE
#[2,]       FALSE    FALSE   FALSE    TRUE
#[3,]       FALSE    FALSE   FALSE   FALSE
#[4,]       FALSE    FALSE   FALSE   FALSE
#[5,]       FALSE    FALSE   FALSE   FALSE

您可以对这些值按列求和以获得匹配数。

result <- colSums(sapply(A, grepl, B))
result

#Cortinarius    Laccaria     Inocybe     Russula 
#          1           0           0           1 

#values with at least one match
names(Filter(function(x) x > 0, result))
#[1] "Cortinarius" "Russula" 

#values with no match
names(Filter(function(x) x == 0, result))
#[1] "Laccaria" "Inocybe"