Search code examples
rfor-loopif-statementappendcross-reference

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


I have a vector A and a list B of vectors v1, v2 and v3. I aim to combine the vectors in list B that contain one or more of the entries of A into a new vector (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)

The result I was hoping for:

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

Solution

  • Here is a one-liner with Map.

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

    Explanation:

    Map applies the anonymous function to every element of its list arguments. Since list(A) has length 1, it is recycled to the length of the list B.
    As for the function, if any element of x, (the vector A) is in y (each of the vectors of B) then y is returned, else NULL is returned.

    Edit

    If B has a dim attribute set, then it can be an object of class "matrix" or of class "data.frame" (or inheriting from one of those classes).

    1. If it is a matrix, coerce to vector and there is no need for 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. If it is a data.frame, unlist where it's as.vector above.

    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