Select everything except strings with a plus sign regex

Viewed 194

Suppose I have the following data frame in R:

df <- tribble(
    ~id, ~key,
    1, "+999..3762962",
    2, "0677219-30911",
    3, "-739812//3918",
    4, "+273$$8279838",
    5, "1904-03940538",
    6, NA
)

I want to filter every row that does not have a plus sign.

According to regex rules, with "[^...]" I should be able to exclude any character I want. However, when trying something like:

library(tidyverse)

df %>% 
    filter(str_detect(key, "[^\\+]"))

It doesn't work out, and it ends up filtering everything except missing values (it excludes the 6th row).

What am I doing wrong here? I have tried searching for similar questions, but they ask for very specific selections with regex, thus, the resulting code/suggestion is practically indecipherable to me. I believe the answer to this is very simple.

Thanks.

2 Answers

We could either search for the presence of + character in the string with str_detect and specify negate = TRUE (from @thelatemail) (Here the | with is.na - is done to return the rows with missing values - by default, filter removes those NA rows)

library(dplyr)
library(stringr)
df %>% 
   filter(str_detect(key, fixed('+'), negate = TRUE)|is.na(key))
# A tibble: 4 x 2
#    id key          
#  <dbl> <chr>        
#1     2 0677219-30911
#2     3 -739812//3918
#3     5 1904-03940538
#4     6 <NA>         

Or if we use the OP's code, make sure to specify the start (^) and $ of the string i.e. one or more characters that are not a + ([^+]+) from the start (^) till the end ($) of the string

df %>% 
   filter(str_detect(key, '^[^+]+$')|is.na(key))
# A tibble: 4 x 2
#     id key          
#  <dbl> <chr>        
#1     2 0677219-30911
#2     3 -739812//3918
#3     5 1904-03940538
#4     6 <NA>        

Base R version with grep :

df[grep('+', df$key, fixed = TRUE, invert = TRUE),]

#     id key          
#  <dbl> <chr>        
#1     2 0677219-30911
#2     3 -739812//3918
#3     5 1904-03940538
#4     6 NA           
Related