Использование функции foreach для параллелизации вычислений - PullRequest
0 голосов
/ 13 сентября 2018

У меня есть папка, содержащая 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 parallel и for each функцию?

Ответы [ 2 ]

0 голосов
/ 13 сентября 2018

Ниже приведен скелет для вашего 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)

Но распараллеливание действительно лучше, когда время вычислений (ЦП) на независимую итерацию выше, чем оставшиеся операции.В вашем случае улучшение может быть незначительным, потому что каждое ядро ​​должно иметь доступ к диску для чтения и записи, а поскольку запись является физической операцией, может быть лучше сделать это последовательно (безопаснее для оборудования и в конечном итоге более эффективно).иметь независимые расположения на диске для каждого файла по сравнению с общим расположением для нескольких файлов, нуждающихся в индексах и т. д., чтобы различать их для вашей ОС - предыдущее подтверждение нужно, это всего лишь мысль).

HTH

Бастьен

0 голосов
/ 13 сентября 2018

Пакет pbapply - это самый простой способ распараллеливания

library (pbapply)

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