我正在尝试从非结构化文本中提取子字符串。例如,假设一个国家/地区名称向量:
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
删除所有不匹配项,然后删除然后删除空值的行。我也一直在使用stringr包中的str_extract
,但是没有成功获得正则表达式的句子。非常感谢任何帮助!
答案 0 :(得分:3)
<强> 1。 stringr 强>
我们可以首先使用'indx'(将'countries'向量折叠形成)形成'text.df'作为'grep'中的模式,然后使用'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。 stringi 强>
我们还可以使用stri_extract
stringi
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
答案 1 :(得分: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
答案 2 :(得分:3)
创建模式p
,然后使用strapply
为每个不匹配的组件text
的{{1}}的每个组件提取匹配项。最后使用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)))
使用dplyr它也可以写成如下(使用上面的 ID text
1 1 United States
4 4 Israel
5 5 Canada
):
p