Home > OS >  Choosing words not containing specific strings in R
Choosing words not containing specific strings in R

Time:04-24

I would like to choose not containing a specific word but I have some conditions to do it and I couldn't think how can I conduct this. Let me explain what I would to do:

I don't want to delete any column in my data frame but I would like to delete some strings in a specific cell. First of all "a a", "b b", "c c", etc. are groups and some of groups has "(s)" near it.

  1. If a cell contains more than one group and one of it has "(s)" delete that group and use first group without "(s)" .
  2. If a cell contains only one group and it has "(s)", remain as it is.
  3. If a cell contains only one group and it does not have "(s)", remain as it is.
  4. If a cell starting a group without "(s)", remain as it is.

I attached my data at the end of this thread.

My data looks like this:

ID COL1
1 a a (s), b b (s), c c
2 d d, e e (s), f f
3 a a (s), b b, f f
4 k k (s), b b (s), c c
5 y y, a a (s), e e (s), g g
6 a a (s), c c, f f
7 k k (s), b b (s), c c
8 e e (s), k k (s), b b (s), f f
9 d d, e e (s), f f
10 k k (s), b b (s), c c
11 d d, a a (s), f f
12 q q (s), t t, h h
13 m m, h h
14 r r, d d
15 q q (s)
16 r r
17 q q (s)
18 c c
19 k k (s)
20 d d
21 m m, k k (s)
22 r r
23 k k (s), b b (s), q q (s), c c
24 a a (s), k k (s), b b (s), f f, d d
25 h h
26 q q (s), a a (s), c c
27 k k (s)
28 e e (s)
29 m m
30 r r

And I would like to make this data like this:

ID COL1
1 c c
2 d d
3 b b
4 c c
5 y y
6 c c
7 c c
8 f f
9 d d
10 c c
11 d d
12 t t
13 m m
14 r r
15 q q (s)
16 r r
17 q q (s)
18 c c
19 k k (s)
20 d d
21 m m
22 r r
23 c c
24 f f
25 h h
26 c c
27 k k (s)
28 e e (s)
29 m m
30 r r
> structure(list(ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 
29, 30), COL1 = c("a a (s), b b (s), c c", "d d, e e (s), f f", 
"a a (s), b b, f f", "k k (s), b b (s), c c", "y y, a a (s), e e (s), g g", 
"a a (s), c c, f f", "k k (s), b b (s), c c", "e e (s), k k (s), b b (s), f f", 
"d d, e e (s), f f", "k k (s), b b (s), c c", "d d, a a (s), f f", 
"q q (s), t t, h h", "m m, h h", "r r, d d", "q q (s)", "r r", 
"q q (s)", "c c", "k k (s)", "d d", "m m, k k (s)", "r r", "k k (s), b b (s), q q (s), c c", 
"a a (s), k k (s), b b (s), f f, d d", "h h", "q q (s), a a (s), c c", 
"k k (s)", "e e (s)", "m m", "r r")), class = c("tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -30L))

CodePudding user response:

Here is a way. It uses a series of gregexpr/regmatches to detect and extract regular expressions and *apply loops to keep elements of the resulting vectors.

df1 <- 
  structure(list(
    ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 
           17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30), 
    COL1 = c("a a (s), b b (s), c c", "d d, e e (s), f f", 
             "a a (s), b b, f f", "k k (s), b b (s), c c", "y y, a a (s), e e (s), g g", 
             "a a (s), c c, f f", "k k (s), b b (s), c c", "e e (s), k k (s), b b (s), f f", 
             "d d, e e (s), f f", "k k (s), b b (s), c c", "d d, a a (s), f f", 
             "q q (s), t t, h h", "m m, h h", "r r, d d", "q q (s)", "r r", 
             "q q (s)", "c c", "k k (s)", "d d", "m m, k k (s)", "r r", "k k (s), b b (s), q q (s), c c", 
             "a a (s), k k (s), b b (s), f f, d d", "h h", "q q (s), a a (s), c c", 
             "k k (s)", "e e (s)", "m m", "r r")), 
    class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -30L))


m <- gregexpr("[[:alpha:]] [[:alpha:]] \\(s\\)", df1$COL1)
tmp <- sapply(seq_along(df1$COL1), \(i) {
  len <- attr(m[[i]], "match.length")[1]
  if(len != nchar(df1$COL1[i])) {
    regmatches(df1$COL1[i], m[i]) <- ""
  }
  df1$COL1[i]
})

m <- gregexpr(", *", tmp)
tmp <- regmatches(tmp, m, invert = TRUE)
tmp <- sapply(tmp, \(x) x[nchar(x) != 0L])
df1$COL1 <- sapply(tmp, `[`, 1)

df1
#> # A tibble: 30 x 2
#>       ID COL1 
#>    <dbl> <chr>
#>  1     1 c c  
#>  2     2 d d  
#>  3     3 b b  
#>  4     4 c c  
#>  5     5 y y  
#>  6     6 c c  
#>  7     7 c c  
#>  8     8 f f  
#>  9     9 d d  
#> 10    10 c c  
#> # ... with 20 more rows

Created on 2022-04-22 by the reprex package (v2.0.1)

  • Related