Я пытаюсь узнать, как использовать параллельную обработку в 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 "Market" для автомобилей и 2 "Car_type".Потребители, возможно, купили автомобили на любом рынке.Я должен рассчитать значение ("Final_value") из данного усеченного нормального распределения.Это значение зависит только от значения Variable1 данного рынка.Вот почему я использую внешний цикл for.Средство усеченного нормального распределения зависит от значения Variable1 (max (Variable1) на рынке, если Car_purchased == 1, или заданного значения, если Car_purchased == 0).Эта версия кода работает идеально (хотя она не оптимизирована для скорости).
Проблема
Далее я хотел бы использовать параллельную обработку для внешнего цикла for, т.е. дляпетля между рынками, поскольку Final_value рынка зависит только от наблюдений внутри рынка.
К сожалению, я знаю, как реализовать параллельную обработку для каждой строки набора данных.Например,Мой код (приведенный ниже) назначает 1-ю строку 1-му ядру, 2-ю строку 2-му ядру и т. д. Это неэффективно и занимает много времени, так как каждая строка должна создать подмножество, а затем найти максимумподмножества.
Моя неэффективная версия
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)
Это крайне неэффективно, если я запускаю его на наборе данных размером> 100 КБ (мой фактический набор данных составляет около 1,2 миллиона строк). Однако я не смог реализовать распараллеливание на уровне рынка, где параллельные вычисления будут выглядеть следующим образом: Запустите вычисления для City1 в 1-м ядре, City2 во 2-м ядре и т. Д. Может кто-нибудь помочь, пожалуйста?Любая помощь приветствуется.Спасибо.
PS Мои извинения за длинный вопрос.Я просто хотел показать все версии кода, которые я использовал.