我试图在电子邮件列表中找到~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.
我有什么想法可以通过使用索引或相等来加速这个? 我真的很期待在这个问题上获得帮助。
非常感谢 克莱门
答案 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]
我在搜索好运时也将所有文本更改为小写(这可能不是最不敏感的方式,但它看起来对我来说最明显)。