在R中for循环用于模式匹配的更快的替代方法

时间:2013-07-17 08:27:32

标签: r plyr apply

我正在研究一个问题,其中我需要两个数据框数据和缩写,我想将数据中存在的所有缩写替换为各自的完整形式。直到现在我以下列方式使用for-loops

abb <- c()
for(i in 1:length(data$text)){
  for(j in 1:length(AbbreviationList$Abb)){
    abb <- paste("(\\b", AbbreviationList$Abb[j], "\\b)", sep="")
    data$text[i] <- gsub(abb, AbbreviationList$Fullform[j], tolower(data$text[i]))
  }
}

缩写数据框看起来像下图,可以使用以下代码生成

enter image description here

Abbreviation <- c(c("hru", "how are you"), 
                  c("asap", "as soon as possible"), 
                  c("bf", "boyfriend"), 
                  c("ur", "your"), 
                  c("u", "you"),
                  c("afk", "away from keyboard"))
Abbreviation <- data.frame(matrix(Abbreviation, ncol=2, byrow=T), row.names=NULL)

名称(缩写)&lt; - c(“abb”,“Fullform”)

并且数据仅仅是具有1列的数据帧,每列具有文本串,这也可以使用以下代码生成。

enter image description here

data <- data.frame(unlist(c("its good to see you, hru doing?", 
                            "I am near bridge come ASAP",
                            "Can u tell me the method u used for",
                            "afk so couldn't respond to ur mails",
                            "asmof I dont know who is your bf?")))
names(data) <- "text"

最初,我的数据框有大约1000个观察值和大约100的缩写。所以,我能够运行分析。但是现在数据已经增加到接近50000并且我在处理它时遇到了困难,因为有两个for-loops使得该过程非常慢。你能否提出一些更好的for-loop替代方案,并举例解释如何在这种情况下使用它。如果通过矢量化方法可以更快地解决这个问题,那么请建议如何做到这一点。

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

首先,显然没有必要在循环的每次迭代中编译正则表达式。此外,没有必要实际循环data$text:在R中,通常可以使用值可以执行的向量 - 并且R将遍历向量的所有元素并返回向量相同的长度。

Abbreviation$regex <- sprintf( "(\\b%s\\b)", Abbreviation$abb )

for( j in 1:length( Abbreviation$abb ) ) {
    data$text <- gsub( Abbreviation$regex[j], 
                       Abbreviation$Fullform[j], data$text,
                       ignore.case= T )
 }

以上代码适用于示例数据。

答案 1 :(得分:1)

这应该更快,没有副作用。

mapply(function(x,y){
  abb <- paste0("(\\b", x, "\\b)")
  gsub(abb, y, tolower(data$text))
},abriv$Abb,abriv$Fullform)
  1. gsub是矢量化的,所以不要给它一个寻找匹配的字符向量。在这里,我给它数据$ text
  2. 我使用mapply来避免for的副作用。