根据字符串中的以下术语提取数字

时间:2019-05-13 21:20:34

标签: r text nlp

我有一批数据,其中包括一个充满自由格式文本的文本变量。我试图根据字符串中的上下文将某些信息提取到新变量中,然后可以对其进行分析。

我一直在研究qdaptm。我已经用tolowerreplace_abbreviation统一了格式,但似乎无法弄清楚如何实际提取所需的信息。

例如,

library(data.table)
data<-data.table(text=c("Person 1: $1000 fine, 31 months jail", 
                     "Person 2: $500 fine, 45 days jail"))


                                   text
1: Person 1: $1000 fine, 31 months jail
2:    Person 2: $500 fine, 45 days jail

我想做的是根据以下术语提取数字,以创建另外两个变量,即months和days,它们具有相应的值:

data<-data.table(text=c("Person 1: $1000 fine, 31 months jail", 
                        "Person 2: $500 fine, 45 days jail"), 
                 months=c("31",""), 
                 days=c("","45")


                                   text months days
1: Person 1: $1000 fine, 31 months jail     31     
2:    Person 2: $500 fine, 45 days jail          45

我一直在寻找Stack Overflow,但没有找到任何答案,因此希望我不会错过一个答案。但是任何人都可以提供的任何帮助将不胜感激。在文本分析方面还是很新的。

谢谢您的时间!

2 个答案:

答案 0 :(得分:1)

getMonths <- function(str) {
  res <- regmatches(str, regexpr("\\d+\\smonths",str));
  if (length(res)>0) {
    res <- regmatches(res, regexpr("\\d+",res));
  }
  return (ifelse(is.null(res),NA,res))
}

getDays <- function(str) {
  res <- regmatches(str, regexpr("\\d+\\sdays",str));
  if (length(res)>0) {
    res <- regmatches(res, regexpr("\\d+",res));
  }
  return (ifelse(is.null(res),NA,res))
}

d<-tibble::as_tibble( list(text = c("Person 1: $1000 fine, 31 months jail", 
                        "Person 2: $500 fine, 45 days jail")))


d %>% dplyr::mutate( days = sapply(text,getDays), months = sapply(text,getMonths)) 

##  A tibble: 2 x 3
##  text                                   days  months
##  <chr>                                  <chr> <chr> 
##  1 Person 1: $1000 fine, 31 months jail NA    31    
##  2 Person 2: $500 fine, 45 days jail    45    NA

答案 1 :(得分:1)

stringr::str_extract()positive lookahead结合使用,您可以执行以下操作:

data <- dplyr::mutate(data,
                      months = stringr::str_extract(text, "\\d+(?=\\smonths)"),
                      days = stringr::str_extract(text, "\\d+(?=\\sdays)"))

##                                   text months days
## 1 Person 1: $1000 fine, 31 months jail     31 <NA>
## 2    Person 2: $500 fine, 45 days jail   <NA>   45

上面的正则表达式对文本字符串进行了一些假设,即它在数字和单位之间只有一个空格,并且单位始终是复数。更加灵活的是:

data<-data.table(text=c("Person 1: $1000 fine, 31 months jail", 
                        "Person 2: $500 fine, 45 days jail",
                        "Person 3: $1000 fine, 1     month 1 day jail"))

data <- dplyr::mutate(data,
                      months = stringr::str_extract(text, "\\d+(?=\\s*months*)"),
                      days = stringr::str_extract(text, "\\d+(?=\\s*days*)"))

##                                           text months days
## 1         Person 1: $1000 fine, 31 months jail     31 <NA>
## 2            Person 2: $500 fine, 45 days jail   <NA>   45
## 3 Person 3: $1000 fine, 1     month 1 day jail      1    1