R - 如何计算大文本文件的特定字符串的出现次数

时间:2015-09-29 15:06:53

标签: r parallel-processing stringi

我试图在电子邮件列表中找到~10,000个不同位置的出现。 我需要的是一个矢量,每个电子邮件中最常提到的位置,一个频率第二,一个频率第三!

由于我的数据集非常庞大,因此我遇到了问题。我尝试使用stringi和并行程序包但它仍然运行非常slowlx(对于20.000个电子邮件和10.000个位置,大约15分钟)。 输入数据(电子邮件和城市)如下所示:

# libraries
library(doParallel)
library(stringi)

detectCores()
registerDoParallel(cores=7)
getDoParWorkers()

# function
getCount <- function(data, keyword)
{ 
  keyword2 = paste0( "^(", keyword, ")|(", keyword, ")$|[ ](", keyword, ")[ ]" )
  wcount <- stri_count(data, regex=keyword2)
  return(data.frame(wcount))
}

SearchVector = as.vector(countryList2)
Text = g$Message

cityName1 = character()
cityName2 = character()

result = foreach(i=Text, .combine=rbind, .inorder=FALSE, .packages=c('stringi'), .errorhandling=c('remove')) %dopar% 
{

  cities = as.data.frame(t(getCount(i, SearchVector)))
  colnames(cities) = SearchVector

  if ( length(cities[which(cities > 0)]) == 1 ) {
    cityName1 = names(sort(cities, decreasing = TRUE))[1]
    cityName2 = NA
  }
  else if ( length(cities[which(cities > 0)]) > 1 ) {
    cityName1 = names(sort(cities, decreasing = TRUE))[1]
    cityName2 = names(sort(cities, decreasing = TRUE))[2] 
  }

  else  {
    cityName1 = NA
    cityName2 = NA 

  }

  return(data.frame(cityName1, cityName2))
}


g$cityName1 = result[, 1]
g$cityName2 = result[, 2]

这是我使用stringi的代码:

var jobs =
      context.Job
        .Include(j => j.PlannedJobStopDetails
          .Select(jsd => jsd.PlannedTravelStop)
        )
        .Where(
          j => j.DateUpdated >= dateFrom && j.DateUpdated <= dateTo &&
               j.PlannedJobStopDetails.Any(
                 jsd => jsd.DateUpdated >= dateFrom && jsd.DateUpdated <= dateTo
                     && jsd.PlannedTravelStop.PlannedTravelStopStatus == status
                 )
        );
jobs.Dump(); // execute the query in linqpad and dump results.

我有什么想法可以通过使用索引或相等来加速这个? 我真的很期待在这个问题上获得帮助。

非常感谢 克莱门

1 个答案:

答案 0 :(得分:1)

评论这一点有点太乱了,但请试一试:

library(data.table)
library(stringr)

dt = data.table(Text = g$Message, cleantext = tolower(g$Message))
dt[, place := str_extract_all(cleantext, paste0("(", paste(tolower(SearchVector), collapse = ")|("), ")"))]

此问题中的SearchVector也有一些缺失的引号。

对于像这样的事情,

data.table通常是闪电般快速的,但是在子集上尝试它并看看它是否可以接受。

地方栏看起来像是用逗号分隔的一堆地名,但在内部它是一个列表,所以很容易做各种聚合,就像每个文本中的计数位数一样,计算如何很多时候每个地方都被提及等。

dt[, n := lapply(place, length)]; dt
nplace = data.table(place = dt[, unlist(place)])[, .N, place]

我在搜索好运时也将所有文本更改为小写(这可能不是最不敏感的方式,但它看起来对我来说最明显)。