【问题标题】:replace words in R data.frames (Text Mining)替换 R data.frames 中的单词(文本挖掘)
【发布时间】:2011-07-27 13:48:40
【问题描述】:

我正在使用 SQL 和 R 开发文本挖掘解决方案。

首先我从我的 SQL 选择中将数据导入 R,然后用它进行数据挖掘。

这是我得到的:

rawData = sqlQuery(dwhConnect,sqlString) 
a = data.frame(rawData$ENNOTE_NEU)

如果我做一个

a[[1]][1:3]

你看到了结构:

[1] lorem ipsum li ld ee wö wo di dd
[2] la kdin di da dogs chicken
[3] kd good i need some help 

现在我想用我自己的字典做一些数据清理。 一个例子是将 li 替换为 lorem ipsumkd 以及 kdin 替换为 kunde

我的问题是如何为整个数据框做到这一点。

 for(i in 1:(nrow(a)))
    {
        a[[1]][i]=gsub( " kd | kdin " , " kunde " ,a[[1]][i])
        a[[1]][i]=gsub( " li " , " lorem ipsum " ,a[[1]][i])
...
    }

有效,但对于大量数据来说速度很慢。

有没有更好的方法来做到这一点?


为船长干杯

【问题讨论】:

  • 可能是一个尝试的选项:直接在 SQL 中执行此操作或从 R 调用 SQL 命令?
  • SQL 和 gsub 的想法到目前为止都很好。如果速度很重要,您还可以在 Rcpp 中编写自定义函数。

标签: r replace dataframe gsub


【解决方案1】:

gsub 已矢量化,因此您不需要循环。

a[[1]] <- gsub( " kd | kdin " , " kunde " , a[[1]])

更快。


另外,您确定要在正则表达式中添加空格吗?这样您就不会匹配行首或行尾的单词。

【讨论】:

  • +1 用于干净的矢量化解决方案。如果您想为多个列执行此操作,可以使用apply( a, 2, function(x) gsub("kd|kdin","kunde",x) )
  • 谢谢。 apply( a, 2, function(x) gsub("kd|kdin","kunde",x) ) 成功了。正则表达式中的空格是必要的,否则像 makd 这样的东西会被翻译成 makunde 。我有一个庞大的语料库要处理,所以问题会非常多。
【解决方案2】:

替代方法:完全避免使用正则表达式。当您有很多不同的词要搜索时,这最有效,因为除了第一次之外,您将避免文本操作。

a1 <- c("lorem ipsum li ld ee wö wo di dd","la kdin di da dogs chicken","kd good i need some help")
x <- strsplit(a1, " ",fixed=TRUE) # fixed option avoids regexes which will  be slower

replfxn <- function(vec,word.in,word.out) {
  vec[vec %in% word.in] <- word.out
  vec
}

word.in <- "kdin"
word.out <- "kunde"

replfxn(x[[2]],word.in,word.out)

lapply(x,replfxn,word.in=word.in,word.out=word.out)
[[1]]
[1] "lorem" "ipsum" "li"    "ld"    "ee"    "wö"    "wo"    "di"    "dd"   

[[2]]
[1] "la"      "kunde"   "di"      "da"      "dogs"    "chicken"

[[3]]
[1] "kd"   "good" "i"    "need" "some" "help"

对于要搜索的大量单词,我猜这比正则表达式要快。它也更适合数据代码分离,因为它有助于编写合并或类似函数以从文件中读取字典,而不是将其嵌入代码中。

如果您确实需要将其恢复为原始格式(作为空格分隔的字符向量),您可以将paste 应用于结果。

这是计时结果。我的立场是正确的:看起来 gsub 更快!

library(microbenchmark)
microbenchmark(
  gsub( word.in , word.out , a1) ,
  lapply(x,replfxn,word.in=word.in,word.out=word.out) ,
  times = 1000
  )

                                                        expr    min     lq
1                                gsub(word.in, word.out, a1)  42772  44484
2 lapply(x, replfxn, word.in = word.in, word.out = word.out) 102653 106075
  median       uq    max
1  47905  48761.0 691193
2 109496 111635.5 970065

【讨论】:

  • 你是对的。我用 lapply 做了实验,也有同样的经历。事实证明,我的循环非常耗时。
猜你喜欢
  • 2017-04-22
  • 2018-09-21
  • 2015-01-10
  • 2014-01-07
  • 1970-01-01
  • 2017-06-01
  • 2018-05-04
  • 2017-04-10
  • 2018-12-24
相关资源
最近更新 更多