gsub ) only if there is no (

Viewed 162

I am working in R and am trying to remove closing parenthesis only when there is no opening parenthesis. I have tried below and it is not returning the desired output.

test <- data.frame(t1 = c("Book (Pg 1)", "Website Online)", "Journal: 2018)"))
test

test$t2 <- ifelse(str_contains(test$t1, "("), test$t1, gsub("(", '', test$t1))

I am hoping to return test$t2 as "Book (Pg1)", "Website Online", "Journal: 2018"

3 Answers

You accidentally used an open parenthesis ("(") instead of a close parenthesis (")") in your gsub(). Also, since ( and ) are regex metacharacters, you need to escape them twice (once for R strings and once for regex) with a double backslash ("\\").

Using the vectorized grepl as a base solution, we get:

test$t2 <- ifelse(grepl("\\(", test$t1), test$t1, gsub("\\)", "", test$t1))

which yields the following output for test:

               t1             t2
1     Book (Pg 1)    Book (Pg 1)
2 Website Online) Website Online
3  Journal: 2018)  Journal: 2018

You could also do:

sub("([(].*[)])|[)]", '\\1', test$t1)
[1] "Book (Pg 1)"    "Website Online" "Journal: 2018" 

Updated Solution Thanks to a great tip from dear @r2evens, we could use the following solution to spare rowwise to have a more efficient solution:

test %>%
  mutate(t1 = if_else(grepl("\\(.*\\)", t1), t1, gsub("\\)", "", t1)))

              t1
1    Book (Pg 1)
2 Website Online
3  Journal: 2018

Original solution You can also use the following solution:

library(dplyr)
library(stringr)

test %>%
  rowwise() %>%
  mutate(t1 = case_when(
    all(str_detect(t1, c("\\(", "\\)"))) ~ t1,
    TRUE ~ str_replace(t1, "\\)", "")
  ))

# A tibble: 3 x 1
# Rowwise: 
  t1            
  <chr>         
1 Book (Pg 1)   
2 Website Online
3 Journal: 2018 
Related