detect presence/absence of elements in nested lists

I am trying to check whether nesed lists contain elements of a vector.
My result with str_detect is pretty close, but what I want is simply a vector for the lists (TRUE TRUE FALSE) and not the results for each element in the list (as I have now).
I assume I am lacking a subsequent step?

I am alson not clear why I am getting the warning with str_detect.

Many thanks!

library(tidyverse)
x <- list(list1=c("a","A","y"),
          list2=c("b","B","y"),
          list3=c("c", "C","y"))

y <- c("a","B")
map(x, ~str_detect(., y))

EDIT: i just realised that my approach above is actually wrong. If the sequence in y would be c("B", "a")
the result contains no TRUE. So the command is contingent on the sequence, and this should not be the case.

#> Warning in stri_detect_regex(string, pattern, opts_regex = opts(pattern)):
#> longer object length is not a multiple of shorter object length
#> Warning in stri_detect_regex(string, pattern, opts_regex = opts(pattern)):
#> longer object length is not a multiple of shorter object length

#> Warning in stri_detect_regex(string, pattern, opts_regex = opts(pattern)):
#> longer object length is not a multiple of shorter object length
#> $list1
#> [1]  TRUE FALSE FALSE
#> 
#> $list2
#> [1] FALSE  TRUE FALSE
#> 
#> $list3
#> [1] FALSE FALSE FALSE

map(x, ~has_element(., y))
#> $list1
#> [1] FALSE
#> 
#> $list2
#> [1] FALSE
#> 
#> $list3
#> [1] FALSE

Created on 2019-05-23 by the reprex package (v0.3.0)

This short function will do it:

detect_string <- function(your_list, vector_strings){
  lapply(your_list, function(x) {
    if(TRUE %in% str_detect(x, paste(vector_strings, collapse = "|"))){
      TRUE
    } else {FALSE}
  })
}

The test with your data:

x <- list(list1=c("a","A","y"),
          list2=c("b","B","y"),
          list3=c("c", "C","y"))
y <- c("a","B")

detect_string(x,y)
3 Likes

Many thanks. Works like a charm.

Out of curiousity, if there is a more 'direct' solution with purrr e.g. has_element
or some I would be eager to see that.

I'd try with this:

x <- list(list1 = c("a", "A", "y"),
          list2 = c("b", "B", "y"),
          list3 = c("c", "C", "y"))

y <- c("a", "B")

# lapply(X = x, FUN = function(t) any(y %in% t))
purrr::map_lgl(.x = x,
               .f = ~ any(y %in% .))
#> list1 list2 list3 
#>  TRUE  TRUE FALSE
4 Likes

:ok_hand: excellent. many thx.

Thanks for that. That's obviously way more elegant :slight_smile:

you should check this out buddy

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.