Home > Mobile >  case_when & %in%
case_when & %in%

Time:03-16

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
  • Related