我有一个包含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))
我想读取一个文件并计算每年的总降雨量 并再次写入输出。我可以通过多种方式执行此操作:
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)
}
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))
我想使用foreach
实现这一目标。我如何并行执行上述任务
使用do parallel
和for each
函数?
答案 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)