我正在尝试学习如何在R中使用并行处理。下面提供了数据和代码的快照。
library(truncnorm)
#Creating a mock dataframe
Market =c('City1','City2','City3','City4','City5','City2','City4','City1','City3','City5')
Car_type = c('A','A','A','A','A','B','B','B','B','B')
Variable1=c(.34,.19,.85,.27,.32,.43,.22,.56,.17,.11)
Car_purchased = c(1,0,0,1,0,1,0,0,1,1)
Market_data = data.frame(Market,Car_type,Variable1,Car_purchased)
Market_data2=do.call("rbind", replicate(100, Market_data, simplify = FALSE))
#Create a bigger dataset
Market_data2$Final_value = 0 #create a column of for future calculation
empty_list = list()
Car_Value=function(data){
market_list=unique(Market_data2$Market)
for (m in market_list){
market_subset = Market_data2[which(Market_data2$Market==m),]
for (i in 1:nrow(market_subset)){
if(market_subset[i,'Car_purchased']==1){
market_subset[i,'Final_value'] = rtruncnorm(1,a=-10,b=0,mean=max(market_subset$Variable1),sd=1)
} else{
market_subset[i,'Final_value'] = rtruncnorm(1,a=-10,b=0,mean = market_subset[i,'Variable1'],sd=1)
}
}
empty_list=rbind(empty_list,market_subset)
}
return(empty_list)
}
get_value = Car_Value(data=Market_data2)
在上面的示例中,总共有5个汽车“市场”和2个“ Car_type”。消费者可能在两个市场上都购买了汽车。我必须从给定的截断正态分布中计算一个值(“ Final_value”)。该值仅取决于给定市场的Variable1的值。这就是为什么我使用外部for循环。截断正态分布的均值取决于Variable1的值(如果Car_purchased == 1,则为市场中的max(Variable1);如果Car_purchased == 0,则为给定值)。此版本的代码运行得很好(尽管尚未针对速度进行优化)。
接下来,我要对外部for循环(即整个市场的循环)使用并行处理,因为市场的Final_value仅取决于市场内的观察结果。
不幸的是,我只知道如何为数据集的每一行实现并行处理。例如。我的代码(下面提供)将第一行分配给第一核,将第二行分配给第二核,依此类推。这效率低下,并且需要花费很长时间,因为每行必须创建子集,然后找到子集的最大值。
library(parallel)
library(foreach)
library(doParallel)
library(iterators)
library(utils)
library(truncnorm)
cl=parallel::makeCluster(4,type="PSOCK")
registerDoParallel(cl)
clusterEvalQ(cl, {library(truncnorm)})
Car_Value_Parallel <- function(market_data){
output <- foreach(x = iter(market_data, by = "row"), .combine = rbind) %dopar% {
market_subset = market_data[which(market_data$Market==x$Market),]
if(x['Car_purchased']==1){
x['Final_value'] = rtruncnorm(1,a=-10,b=0,mean=max(market_subset$Variable1),sd=1)
} else{
x['Final_value'] = rtruncnorm(1,a=-10,b=0,mean = x['Variable1'],sd=1)
}
return(x)
}
output
}
get_value_parallel = Car_Value_Parallel(market_data = Market_data2)
stopCluster(cl)
如果我在大小> 100K的数据集上运行它,效率将非常低(我的实际数据集约为120万行)。 但是,我无法在市场级别实现并行化,并行计算将如下:在第一个核心中运行City1,在第二个核心中运行City2,依此类推。救命?任何帮助表示赞赏。谢谢。
P.S。对于长期的问题,我深表歉意。我只想显示我使用过的所有代码版本。