【问题标题】:Populate column with string used for matching using data.tables使用 data.tables 使用用于匹配的字符串填充列
【发布时间】:2018-11-05 06:40:12
【问题描述】:

这里我创建了两个data.tables

library(data.table)
library(stringr)

mydt <- data.table(summary=c("Denial of Service vulnerability in BIND 8 Releases",
                          "Denial of Service vulnerabilities in BIND 4.9 and BIND 8",
                          "Buffer overflow in NFS mountd gives root access",
                          "Buffer overflow in statd allows root privileges.",
                          "Cross-site scripting (XSS) vulnerability in Open-Xchange",
                          "SQL injection vulnerability in mod_accounting.c in the"),
                    wascname=c(NA,NA,NA,NA,NA,"SQL Injection"))

 wasc <- data.table(wascname=c("Abuse of Functionality",
                              "Cross-Site Scripting",
                              "Buffer Overflow",
                              "Denial of Service",
                              "SQL Injection"))

mydt 的输出

我在这里使用用于匹配的字符串填充列的解决方案。

mydt$wascname <-
   sapply(1:nrow(mydt), function(x)
     ifelse(
       is.na(mydt$wascname[x]),
       wasc$wascname[str_detect(mydt$summary[x],
                                     regex(wasc$wascname, ignore_case = TRUE))],
       mydt$wascname[x]
     ))

输出

我想使用 data.table 表单 DT[i, j, by] 来实现相同的结果。我尝试了不同的解决方案,我无法使用DT 表单开始工作。

我在睡觉时对此进行了更多思考,并重写了一个解决方法以实现DT[i, j, by] 表单。请参阅下面的解决方法,它可以提供我想要的输出:

 mydt[ , wascname:= sapply(1:nrow(mydt),function(x)
   ifelse(is.na(wascname[x]),
          wasc$wascname[str_detect(summary[x],
                                   regex(wasc$wascname, ignore_case = TRUE))],
          wascname[x]))]

【问题讨论】:

  • 你可以尝试使用普通的if else 语句使用grepl
  • 抱歉grepl 不起作用,因为您必须将列转换为单个模式字符串,这会导致匹配中使用的字符串丢失
  • grepl 将与此 wasc[ , .(summary = mydt$summary[grepl(wascname, mydt$summary, ignore.case = T)]), by = wascname] 一起使用,但我对这个答案感到不满意。
  • 表之间的字符串匹配有一些特性请求。 Fwiw,我把你的 Q 链接到了这个:github.com/Rdatatable/data.table/issues/636
  • @utubun 您的解决方案是使用向量 wasc 创建一个新的 data.table。我希望它保持原样(向量),因为我会不断添加它,例如当有新的WASC names 时。 mydt$summary 列用于搜索其中是否存在来自wasc$wascname 向量的字符串。如果它确实使用来自wasc$wascname 的值填充mydt$wascname。我添加了一个我醒来后想到的解决方法。有更好的方法吗? @Frank 感谢您在 github 上提交问题。你能解释一下你提出的解决方案是做什么的吗?

标签: r data.table


【解决方案1】:
library(stringr)
library(tidyverse)

df2<- mydt %>%
  mutate(match = str_extract(tolower(mydt$summary), str_c(tolower(wasc), collapse = "|")))

这将提供您想要的输出。

带有 tidyverse 的 stringr 将在这种情况下工作。

确保将 wasc 保存为列表

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-08
    • 1970-01-01
    • 2012-01-26
    • 1970-01-01
    • 1970-01-01
    • 2019-06-14
    • 2015-07-29
    • 1970-01-01
    相关资源
    最近更新 更多