Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to search for patterns that are not exactly same each time?

Tags:

search

r

I have a list like this:

 list <- c("xxx 23 cut", "yyy", "zzz", "www 55 cut", "kkk", "ggg", "yyy", "eee 7 cut", "ccd" )

The searching patter in this case is "any-number cut". Thus, to visualize the list in a better way, the list is in the following pattern

"before item (=xxx) "  "any number cut (= 23 cut)"
"after item (=yyy)"
"after item (=zzz)"
"before item (=www) "  "any number cut (= 55 cut)"
"after item (=kkk)"
"after item (=ggg)"
"after items (=yyy)"
"before item (=eee) "  "any number cut (= 7cut)"
"after item (=cce)"

I want place the "before items" to column 1, until it found another "any number cut" pattern, and put the "after items" to column 2. The final results would as follows:

xxx yyy
xxx zzz
www kkk
www ggg
www yyy
eee ccd

Could experts teach me how to do it with R? I learn from previous stackoverflow messages that R can search for fixed items (e.g. cut) and strsplit them into different cells. The challenge here (to me) is the searching pattern is changing that the number before the word "cut" is different for each of them. what is the most efficient way to search and cut it in the right place using R?

like image 760
a83 Avatar asked Jan 19 '23 14:01

a83


1 Answers

The following works with your example data:

x <- c("xxx 23 cut", "yyy", "zzz", "www 55 cut", "kkk", "ggg", "yyy", "eee 7 cut", "ccd" )

First, create a regex pattern to use with grep: The following pattern searches for digits (\d) followed by a space and the word cut. See ?regexp and ?grep for details.

cut_pattern <- "\\d* cut"

cut_positions <- grep(cut_pattern, x)
cut_repeat <- c(cut_positions[-1], length(x) + 1) - cut_positions -1
before_items <- rep(x[cut_positions], times=cut_repeat)
after_items <- x[!grepl(cut_pattern, x)]

data.frame(
    before = before_items,
    after  = after_items
)

The results:

      before after
1 xxx 23 cut   yyy
2 xxx 23 cut   zzz
3 www 55 cut   kkk
4 www 55 cut   ggg
5 www 55 cut   yyy
6  eee 7 cut   ccd

I will leave it as an exercise to you to do the cleanup of the data in column 1. Hint: Use str_extract in package stringr. You can refer to this question: How can I use back references with `grep` in R? for examples of how to do this. Further hint, your patterns should be something like "(.*) \\d* cut".

like image 97
Andrie Avatar answered Jan 30 '23 19:01

Andrie