3

我正在尝试从非结构化文本中提取子字符串。例如,假设一个国家名称向量:

countries <- c("United States", "Israel", "Canada")

如何传递此字符值向量以从非结构化文本中提取精确匹配。

text.df <- data.frame(ID = c(1:5), 
text = c("United States is a match", "Not a match", "Not a match",
         "Israel is a match", "Canada is a match"))

在此示例中,所需的输出将是:

ID     text
1      United States
4      Israel
5      Canada

到目前为止,我一直在使用gsub删除所有不匹配项,然后删除然后删除具有空值的行。我也一直在使用str_extractstringr 包,但没有成功让正则表达式的参数正确。任何帮助将不胜感激!

4

3 回答 3

3

这是一种方法data.table

library(data.table)
##
R>  data.table(text.df)[
    sapply(countries, function(x) grep(x,text),USE.NAMES=F),
    list(ID, text = countries)]
   ID          text
1:  1 United States
2:  4        Israel
3:  5        Canada
于 2015-03-22T16:32:40.023 回答
3

1. 纵梁

我们可以首先使用'indx'(由折叠'countries'向量形成)作为'grep'中的模式来子集'text.df',然后使用'str_extract'从'text'列中获取模式元素,分配到子集数据集的“文本”列(“text.df1”)

library(stringr)
indx <- paste(countries, collapse="|")
text.df1 <- text.df[grep(indx, text.df$text),]
text.df1$text <- str_extract(text.df1$text, indx)
text.df1
#  ID          text
#1  1 United States
#4  4        Israel
#5  5        Canada

2.基础R

在不使用任何外部包的情况下,我们可以删除“ind”中的字符以外的字符

text.df1$text <- unlist(regmatches(text.df1$text, 
                           gregexpr(indx, text.df1$text)))

3. 弦乐

我们也可以使用更快stri_extractstringi

library(stringi)
na.omit(within(text.df, text1<- stri_extract(text, regex=indx)))[-2]
#  ID         text1
#1  1 United States
#4  4        Israel
#5  5        Canada
于 2015-03-22T16:29:35.620 回答
3

创建模式, p, 并使用为每个不匹配的组件strapply提取与text返回NA的每个组件的匹配。最后使用删除 NA 值na.omit。这是非破坏性的(即text.df未修改):

library(gsubfn)

p <- paste(countries, collapse = "|")
na.omit(transform(text.df, text = strapply(paste(text), p, empty = NA, simplify = TRUE)))

给予:

  ID          text
1  1 United States
4  4        Israel
5  5        Canada

使用 dplyr 它也可以写成如下(p从上面使用):

library(dplyr)
library(gsubfn)

text.df %>% 
  mutate(text = strapply(paste(text), p, empty = NA, simplify = TRUE)) %>%
  na.omit
于 2015-03-22T17:11:51.783 回答