使用foreach函数并行计算

时间:2018-09-13 12:48:09

标签: r foreach parallel-processing doparallel

我有一个包含5000个csv文件的文件夹,每个文件属于一个位置,并且包含1980年至2015年的每日降雨量。该文件的示例结构如下:

sample.file <- data.frame(location.id = rep(1001, times = 365 * 36), 
                      year = rep(1980:2015, each = 365),
                      day = rep(1:365, times = 36),
                      rainfall = sample(1:100, replace = T, 365 * 36))

我想读取一个文件并计算每年的总降雨量 并再次写入输出。我可以通过多种方式执行此操作:

方法1

for(i in seq_along(names.vec)){

  name <- namees.vec[i]
  dat <- fread(paste0(name,".csv"))

  dat <- dat %>% dplyr::group_by(year) %>% dplyr::summarise(tot.rainfall = sum(rainfall))

 fwrite(dat, paste0(name,".summary.csv"), row.names = F)
}

方法2:

my.files <- list.files(pattern = "*.csv")
dat <- lapply(my.files, fread)
dat <- rbindlist(dat)
dat.summary <- dat %>% dplyr::group_by(location.id, year) %>% 
               dplyr::summarise(tot.rainfall = sum(rainfall))

方法3:

我想使用foreach实现这一目标。我如何并行执行上述任务 使用do parallelfor each函数?

2 个答案:

答案 0 :(得分:1)

下面是foreach request的框架。

require(foreach)
require(doSNOW)
cl <- makeCluster(10, # number of cores, don't use all cores your computer have
                  type="SOCK") # SOCK for Windows, FORK for linux
registerDoSNOW(cl)
clusterExport(cl, c("toto", "truc"), envir=environment()) # R object needed for each core
clusterEvalQ(cl, library(tcltk)) # libraries needed for each core
my.files <- list.files(pattern = "*.csv")
foreach(i=icount(my.files), .combine=rbind, inorder=FALSE) %dopar% {
  # read csv file
  # estimate total rain
  # write output
}
stopCluster(cl)

但是,当每个独立迭代的计算时间(CPU)高于其余操作时,并行化实际上会更好。在您的情况下,改进可能很低,因为每个内核都需要具有驱动器访问权限才能进行读取和写入,并且由于写入是一种物理操作,因此顺序执行可能会更好(对硬件来说更安全,最终效率更高)与多个文件的共享位置相比,在驱动器中每个文件具有独立的位置,需要索引等以区分您的操作系统-以前需要确认,这只是一个想法)。

HTH

巴斯蒂安

答案 1 :(得分:0)

pbapply包是最简单的并行方法

library (pbapply)

mycl <- makeCluster(4)
mylist <- pblapply(my.files, fread, cl = mycl)