Reputation: 83
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")
Upvotes: 1
Views: 87
Reputation: 76460
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.
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
Upvotes: 2
Reputation: 887241
Another option is map2
from purrr
library(purrr)
map2(list(A), B, ~ if(any(.x %in% .y)) .y) %>%
flatten_chr
#[1] "mouse" "cat" "frog" "bird" "cow" "snake"
Upvotes: 1