R:带有列表的交叉引用向量,帮助:根据正命中附加新向量

R: Cross reference vector with list, HELP: append new vector based on positive hits

我有一个向量 A 和一个包含向量 v1、v2 和 v3 的列表 B。我的目标是将列表 B 中包含 A 的一个或多个条目的向量组合成一个新向量 (new_v)。

A <- c("cat", "dog", "bird")
A

B <- list(v1 = c("mike", "fred", "paul"), v2 = c("mouse", "cat", "frog"), v3 = c("bird", "cow", "snake"))
B

new_list <- c()

for(i in names(B)){       
  
  v <- A %in% B[[i]]            ## test for elements of A in vectors of B
  print(v)
  
  if (TRUE %in% v){             ## if TRUE (A is in vector of B), 
                                ## add vector of B to new_v 
    
    append(new_v, unlist(B[i])) ## doesn't do what I want
    
  }
}
dput(new_v)

我希望的结果:

>dput(new_v)
c("mouse", "cat", "frog", "bird", "cow", "snake")

这是 Map.

的单行
unlist(Map(function(x, y) {if(any(x %in% y)) y}, list(A), B))
#[1] "mouse" "cat"   "frog"  "bird"  "cow"   "snake"

解释:

Map 将匿名函数应用于其列表参数的每个元素。由于list(A)的长度为1,所以循环到列表的长度B.
至于函数,如果 x 的任何元素(向量 A)在 yB 的每个向量)中,则 y 是返回,否则返回 NULL

编辑

如果 B 有一个 dim 属性集,那么它可以是 class "matrix" 或 class "data.frame" 的对象(或继承自 classes 之一)。

1.如果是矩阵就强制转为vector,不需要Map.

if(any(A %in% as.vector(B))) B
#     [,1]    [,2]              
#[1,] "mouse" "mice eat rats"   
#[2,] "cat"   "cats eat mice"   
#[3,] "frog"  "frogs frog frogs"

2.如果是data.frame,unlist上面是as.vector.

B2 <- as.data.frame(B)
if(any(A %in% unlist(B2))) B2
#     V1               V2
#1 mouse    mice eat rats
#2   cat    cats eat mice
#3  frog frogs frog frogs
 

另一个选项是 map2 来自 purrr

library(purrr)
map2(list(A), B, ~ if(any(.x %in% .y)) .y) %>%
    flatten_chr
#[1] "mouse" "cat"   "frog"  "bird"  "cow"   "snake"