1

Am trying to extract required words through pattern mapping.

Below is the sample data in the object table


+-----------+-------------------------------------------------------------------------------------------------+
| Unique_Id |                                               Text                                              |
+-----------+-------------------------------------------------------------------------------------------------+
| Ax23z12   | Tool generated code 2015-8134 upon further validation, the tool confirmed the code as 2015-8134 |
+-----------+-------------------------------------------------------------------------------------------------+

using below code

regmatches(table[1,2],gregexpr("2000-\\d{4}",table[1,2]))

am able to extract output as

[[1]]
[1] "2000-0511" "2000-0511"

However the Output am looking for is like below


+-----------+---------------------------------------------------------------------------+-----------+-----------+
| Unique_Id |                                    Text                                   |  Column1  |  Column2  |
+-----------+---------------------------------------------------------------------------+-----------+-----------+
| Ax23z12   | Tool generated code 2015-8134 upon further validation, the tool confirmed | 2015-8134 | 2015-8134 |
|           |   the code as 2015-8134                                                   |           |           |
+-----------+---------------------------------------------------------------------------+-----------+-----------+

Data under text column consists this number multiple times (maximum 7 times) hence looking for dynamic solution

Thank you so much

Santosh
  • 91
  • 9
  • Are you saying you want one column for each match? Why is a vector containing all matches not acceptable to you? – Tim Biegeleisen Sep 17 '17 at 13:40
  • I need to further map these with the definition of the code and not every time the codes in a given row will be same. – Santosh Sep 17 '17 at 14:19

3 Answers3

3

Here is one approach for you. I used the following sample data, which is called foo.

#     id                                                                     text
#  <int>                                                                    <chr>
#1     1                Here is my code, 2015-8134. Here is your code, 2015-1111.
#2     2 His code is 2016-8888, her code is 2016-7777, and your code is 2016-6666

I first extracted numbers with stri_extract_all_regex() for text. This returns a matrix, so I converted it to a data frame. Then, I combined it with the original data set using bind_cols(). The last job is to modify column names. I replaced X in column names with Column in gsub()

library(dplyr)
library(stringi)

out <- stri_extract_all_regex(str = foo$text, pattern = "\\d+-\\d+", simplify = TRUE) %>%
                              data.frame(stringsAsFactors = FALSE) %>%
       bind_cols(foo,. )

names(out) <- names(out) %>%
              gsub(pattern = "X", replacement = "Column")

#     id                                                                     text   Column1   Column2   Column3
#  <int>                                                                    <chr>     <chr>     <chr>     <chr>
#1     1                Here is my code, 2015-8134. Here is your code, 2015-1111. 2015-8134 2015-1111          
#2     2 His code is 2016-8888, her code is 2016-7777, and your code is 2016-6666 2016-8888 2016-7777 2016-6666

DATA

foo <- structure(list(id = 1:2, text = c("Here is my code, 2015-8134. Here is your code, 2015-1111.", 
"His code is 2016-8888, her code is 2016-7777, and your code is 2016-6666"
)), .Names = c("id", "text"), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -2L))
jazzurro
  • 23,179
  • 35
  • 66
  • 76
2

Use stringr and data.table:

1) use str_match_all to extract all matched pattern;

2) use transpose to convert the extracted patterns to columns;

3) construct new data frame by combining the extracted columns with the original one;

library(stringr)
library(data.table)

lst = transpose(str_match_all(df$Text, "2015-\\d{4}"))
data.frame(df, setNames(lst, paste0("Column", seq_along(lst))))
#  Unique_Id                                                                                            Text   Column1   Column2
#1   Ax23z12 Tool generated code 2015-8134 upon further validation, the tool confirmed the code as 2015-8134 2015-8134 2015-8134
#2   By56m22                                           Tool generated code 2015-8134 upon further validation 2015-8134      <NA>
Psidom
  • 209,562
  • 33
  • 339
  • 356
0

Something like this might work for you

df[apply(df, 1, function(x) any(grepl("2000-\\d{4}", x))), ]

See this reproducible example

iris[apply(iris, 1, function(x) any(grepl("set", x))), ]

   # Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1           5.1         3.5          1.4         0.2  setosa
# 2           4.9         3.0          1.4         0.2  setosa
# 3           4.7         3.2          1.3         0.2  setosa
# 4           4.6         3.1          1.5         0.2  setosa
# 5           5.0         3.6          1.4         0.2  setosa
# 6           5.4         3.9          1.7         0.4  setosa
# etc
CPak
  • 13,260
  • 3
  • 30
  • 48