I am trying to use %in% in case_when(), however it doesn't work as it does in general in R. Below is an example. Can someone guide what's wrong with this implementation?
df <- structure(list(name = c("abc A", "xyz B", "jkl C"), text = c("my name is abc A",
"my name is xyz B", "my name is jkl C")), class = "data.frame", row.names = c(NA,
-3L))
x <- c("ABC","B","C")
df %>% mutate(flag=case_when(name %in% x~TRUE, TRUE~FALSE))
Output
name text flag
abc A my name is abc A FALSE
xyz B my name is xyz B FALSE
jkl C my name is jkl C FALSE
Expected output
name text flag
abc A my name is abc A TRUE
xyz B my name is xyz B TRUE
jkl C my name is jkl C TRUE
CodePudding user response:
This is the expected output. The string "abc A" is not found in the vector c("ABC","B","C"), and neither is "xyz B" or "jkl C".
Are you perhaps trying to find string matches? Then you should use str_detect rather than %in%
df %>% mutate(flag=case_when(stringr::str_detect(name, x)~TRUE, TRUE~FALSE))
#> name text flag
#> 1 abc A my name is abc A FALSE
#> 2 xyz B my name is xyz B TRUE
#> 3 jkl C my name is jkl C TRUE
Note that if you only have two options, TRUE or FALSE for an output, you don't need case_when at all.`
df %>% mutate(flag = stringr::str_detect(name, x))
#> name text flag
#> 1 abc A my name is abc A FALSE
#> 2 xyz B my name is xyz B TRUE
#> 3 jkl C my name is jkl C TRUE
Also notice that case 1 should be FALSE, because "abc" does not match "ABC". If you do not care about case, you can use grepl, as AndS describes.
CodePudding user response:
The problem is that you need to collapse x to be a pattern. try this:
library(tidyverse)
df %>%
mutate(flag=grepl(paste(x, collapse = "|"), name, ignore.case = T))
#> name text flag
#> 1 abc A my name is abc A TRUE
#> 2 xyz B my name is xyz B TRUE
#> 3 jkl C my name is jkl C TRUE
