petyar
petyar

Reputation: 535

How do I match a character vector to a list of character vectors in a tibble in R?

I'd like to compare column A in a tibble to column B to see if an element in column A is present in column B. Column A is a character vector. Column B is a list of character vectors. I'd like to do this line by line. I can do this with a loop.

library(tidyverse)

my.tibble = c('a','b','c') %>% tibble
my.list = list(c('a','b'),c('b','c'),c('d','e'))
my.tibble = my.tibble %>% add_column(my.list)

its.in.it = as.list(NULL)
for (i in 1:nrow(my.tibble)){
    its.in.it[[i]] = my.tibble[i,1] %in% unlist(my.tibble[i,2])
}

my.tibble$its.in.it = unlist(its.in.it)
my.tibble

I'm trying to do this with dplyr/purrr or apply. I'm not sure if I should group or nest or split, and there are a lot of combinations.

Upvotes: 3

Views: 873

Answers (4)

petyar
petyar

Reputation: 535

there's also a dplyr version of the apply solution.

my.tibble %>% mutate(its.in.it = . %in% unlist(my.tibble$my.list))

Upvotes: 1

Rui Barradas
Rui Barradas

Reputation: 76615

With apply it would be like this:

apply(my.tibble, 1, function(x) x[1] %in% unlist(x[2]))
#[1]  TRUE  TRUE FALSE

my.tibble$its.in.it <- apply(my.tibble, 1, function(x) x[1] %in% unlist(x[2]))

Upvotes: 3

akrun
akrun

Reputation: 887621

We can use rowwise

library(tidyverse)
names(my.tibble) <- LETTERS[1:2]
my.tibble %>% 
   rowwise() %>%
   mutate(itsinit = A  %in% unlist(B))
# A tibble: 3 x 3
#  A     B         itsinit
#  <chr> <list>    <lgl>  
#1 a     <chr [2]> TRUE   
#2 b     <chr [2]> TRUE   
#3 c     <chr [2]> FALSE  

NOTE: @kath's method with map2 would be faster

Upvotes: 5

kath
kath

Reputation: 7724

You can use map2_lgl which takes two inputs, loops through them and returns a logical vector.

names(my.tibble) <- c("char", "char.list")
my.tibble %>% 
  mutate(its.in.it = map2_lgl(char, char.list, ~ .x %in% .y))

# A tibble: 3 x 3
#   char  char.list its.in.it
#   <chr> <list>    <lgl>    
# 1 a     <chr [2]> TRUE     
# 2 b     <chr [2]> TRUE     
# 3 c     <chr [2]> FALSE  

Upvotes: 6

Related Questions