Eric Fail
Eric Fail

Reputation: 7958

str_detect with outside object pattern (in a tidy way ..)

I would like to optimize my code.

I’m working with str_detect to make a lot of selections, as I would like to optimize my code for the future I would like to select, have a filter pattern defined, based on an externally defined object. I can do that, but I have to strip my way to the object using as.character(). Is it possible to do it in a tidy way?

Working example demonstrating the issue. This is the classical way, it works

> tbl %>% mutate(twentys = case_when(
+   str_detect(fruit, "20") ~ T) )
# A tibble: 4 x 3
      x fruit        twentys
  <int> <chr>        <lgl>  
1     1 apple 20     TRUE   
2     2 banana 20    TRUE   
3     3 pear 10      NA     
4     4 pineapple 10 NA     

This is how I imaged I could do, but it doesn’t way

> twenty <- 20
> tbl %>% mutate(twentys = case_when(
+   str_detect(fruit, twenty) ~ T) )
Error: Problem with `mutate()` input `twentys`.
x no applicable method for 'type' applied to an object of class "c('double', 'numeric')"
i Input `twentys` is `case_when(str_detect(fruit, twenty) ~ T)`.
Run `rlang::last_error()` to see where the error occurred.

This is the cumbersome way, using as.character(), that I would like to optimize.

> tbl %>% mutate(twentys = case_when(
+   str_detect(fruit, as.character(twenty)) ~ T) )
# A tibble: 4 x 3
      x fruit        twentys
  <int> <chr>        <lgl>  
1     1 apple 20     TRUE   
2     2 banana 20    TRUE   
3     3 pear 10      NA     
4     4 pineapple 10 NA     

Upvotes: 1

Views: 105

Answers (2)

akrun
akrun

Reputation: 887951

We can use str_detect

library(dplyr)
library(stringr)
tbl %>%
     mutate(twenty = case_when(str_detect(fruit, str_c(twenty)) ~ TRUE))

Or wrap with paste

tbl %>%
     mutate(twenty = case_when(str_detect(fruit, paste(twenty)) ~ TRUE))

data

tbl <- structure(list(x = 1:4, fruit = c("apple 20", "banana 20", "pear 10", 
 "pineapple 10")), class = "data.frame", row.names = c(NA, -4L))
twenty <- 20

Upvotes: 1

Ronak Shah
Ronak Shah

Reputation: 389325

You can use grepl if you don't want to convert twenty to character.

library(dplyr)
tbl %>% mutate(twentys = case_when(grepl(twenty, fruit) ~ TRUE))

#  x        fruit twentys
#1 1     apple 20    TRUE
#2 2    banana 20    TRUE
#3 3      pear 10      NA
#4 4 pineapple 10      NA

data

tbl <- structure(list(x = 1:4, fruit = c("apple 20", "banana 20", "pear 10", 
"pineapple 10")), class = "data.frame", row.names = c(NA, -4L))
twenty <- 20

Upvotes: 1

Related Questions