【问题标题】:Finding list of word present in column of a Dataframe using Grepl in R使用R中的Grepl查找数据框列中存在的单词列表
【发布时间】:2018-07-11 10:53:34
【问题描述】:

我有一个数据框 df:

df <- structure(list(page = c(12, 6, 9, 65),
text = structure(c(4L,2L, 1L, 3L), 
.Label = c("I just bought a brand new AudiA6", "Get 2 years engine replacement warranty on BMW X6", 
"Volkswagen is the parent company of BMW", "ToyotaCorolla is offering new car exchange offers"), 
class = "factor")), .Names = c("page","text"), row.names = c(NA, -4L), class = "data.frame")

另外,我有一个单词列表:

wordlist <- c("Audi", "BMW", "extended", "engine", "replacement", "Volkswagen", "company", "Toyota","exchange", "brand")

我通过取消列出文本并使用 grepl 从 wordlist 中查找是否存在于列文本中的单词。

library(data.table)
setDT(df)[, match := paste(wordlist[unlist(lapply(wordlist, function(x) grepl(x, text, ignore.case = T)))], collapse = ","), by = 1:nrow(df)]

问题是,我想找到列文本中存在的单词列表的确切单词。 使用 grepl 它还显示部分匹配的单词,例如来自文本的 AudiA6 也部分匹配到单词列表中的单词 Audi。此外,我的数据框非常大,使用 grepl 需要花费大量时间来运行代码。如果可能,请推荐任何其他方法来这样做。我想要这样的东西:

df <- structure(list(page = c(12, 6, 9, 65), 
text = structure(c(4L,2L, 1L, 3L), 
.Label = c("I just bought a brand new AudiA6", "Get 2 years engine replacement warranty on BMW X6", 
 "Volkswagen is the parent company of BMW", "ToyotaCorolla is offering new car exchange offers"),
class = "factor"), match = c("exchange", "BMW,engine,replacement", 
"brand", "BMW,Volkswagen,company")), row.names = c(NA, -4L), 
class = c("data.table", "data.frame"))

【问题讨论】:

    标签: r data.table string-matching grepl


    【解决方案1】:

    在为要提取的每个单词添加单词边界 (\\b) 后,您可以使用 stringr 中的 str_extract_all,以便只考虑完全匹配(并且您需要使用 "|" 折叠所有单词以表示“或”):

    sapply(stringr::str_extract_all(df$text, paste("\\b", wordlist, "\\b", sep="", collapse="|")), paste, collapse=",")
    # [1] "exchange"               "engine,replacement,BMW" "brand"                  "Volkswagen,company,BMW"
    

    如果你想把它放在你的data.table

    df[, match:=sapply(stringr::str_extract_all(text, paste("\\b", wordlist, "\\b", sep="", collapse="|")), paste, collapse=",")]
    df
    #   page                                              text                  match
    #1:   12 ToyotaCorolla is offering new car exchange offers               exchange
    #2:    6 Get 2 years engine replacement warranty on BMW X6 engine,replacement,BMW
    #3:    9                  I just bought a brand new AudiA6                  brand
    #4:   65           Volkswagen is the parent company of BMW Volkswagen,company,BMW
    

    【讨论】:

    • 或者稍微短一点的模式...sprintf("\\b(%s)\\b", paste(wordlist, collapse="|"))
    • @Frank 确实更好:-)
    • 我怎样才能只对添加到 df 中的每个新行使用它。我正在从 sql server 读取这些数据。我只想在添加新行时实现此代码。原因是在整个数据库上运行需要很长时间。感谢您的解决方案。
    • @Fraxxx 您可以将行的索引放在i 地方:df[newrow1:nrow(df), match:=sapply(stringr::str_extract_all(text[newrow1:nrow(df)], ...)]
    • @Cath 我没有得到您在上述评论中提到的内容。你能更新你的答案。我不明白第 i 个位置的行的索引。例如,我有 25000 行,一段时间后我将添加 50 个新行。现在,我有 25050 行,我将再次向数据库添加更多行。这将继续下去。所以我想在每次向数据库添加新行时执行这个操作。
    猜你喜欢
    • 2020-06-19
    • 2021-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-20
    • 2014-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多