giovannotti
giovannotti

Reputation: 138

map pattern vector with string vector

I'd like to find the first occurrence of an element of a pattern vector in a string vector and get an output vector of these strings where non-matches should be assigned to NA. Additionally, I'd like to use a compact vectorized solution for this problem (preferably a tidyverse solution).

library(stringr)
library(purrr)

Example:

patterns1 <- c("101", "102", "103", "101")
patterns2 <- c("101", "102", "103", "999", "101")
strings <- c("101a", "101a", "a102a", "aa103a")

For patterns1 this works because every element exists in strings:

map_chr(patterns1, function(x) detect(strings, str_detect, x))
# [1] "101a"   "a102a"  "aa103a" "101a"

But with patterns2 map_chr gives an error:

map_chr(patterns2, function(x) detect(strings, str_detect, x))
# Error: Result 4 is not a length 1 atomic vector

because detect returns NULL if the detection fails. Or do you recommend to use a workaround with map instead of map_chr and transform NULL elements to NA?

map(patterns2, function(x) detect(strings, str_detect, x))
# [[1]]
# [1] "101a"
#
# [[2]]
# [1] "a102a"
#
# [[3]]
# [1] "aa103a"
#
# [[4]]
# NULL
#
# [[5]]
# [1] "101a"

Upvotes: 1

Views: 384

Answers (1)

akrun
akrun

Reputation: 886938

We can create a condition

map_chr(patterns2, ~ detect(strings, str_detect, .x) %>% 
                               if(length(.) > 0) . else NA)
#[1] "101a"   "a102a"  "aa103a" NA       "101a"  

Or concatenate with NA and take the first value

map_chr(patterns2, ~ c(detect(strings, str_detect, .x), NA)[1])
#[1] "101a"   "a102a"  "aa103a" NA       "101a"  

Upvotes: 1

Related Questions