如何使用apply()正确包装R函数以实现并行处理?

时间:2018-02-07 20:27:00

标签: r function parallel-processing

我有一个功能,可以创建每个国家/地区每年捕获鱼类的图表,并将该图表放入一个制图清单中,具体取决于我喂它的年份:

fishtogram <- function(year) {
  dfname <- paste0("carto", year) # name of the cartogram being made
  map_year <- get(paste0("map", year), map_years) # 'map_year' contains one SpatialPolygonsDataFrame of a year of fishing/country data pulled from the list of spdf's 'map_years'
  carto_maps[[dfname]] <<- cartogram(map_year, "CATCH", itermax=1) # This is the part that takes forever. Create cartogram named 'dfname', chuck it into the carto_maps list
  plot(carto_maps[[dfname]], main=dfname) # plot it 
  print(paste("Finished", dfname, "at", Sys.time())) # print time finished cartogram
  writeOGR(obj = carto_maps[[dfname]], dsn = "Shapefiles", layer = dfname, driver = "ESRI Shapefile", overwrite_layer=TRUE) # Save cartogram as shapefile
}

最初这一切都在for循环中(1950 - 2014年)并且它完成了工作,只是极其缓慢。让我失速的部分是cartogram功能。目前,生产一个制图大约需要一个小时,占用我CPU的约13%。我想尝试使用并行处理一次制作3-4个制图,并希望加快速度。

如何正确地将它包装在一个应用函数中,以循环我想要的几年并使用并行处理?我一直在使用this R bloggers post作为指导。我的尝试:

lapply(seq(1975, 2014, 10), fishtogram, .parallel=TRUE)

 >Error in FUN(X[[i]], ...) : unused argument (.parallel = TRUE)

感谢@patL告诉我使用lapply vs apply

我的代码&amp;数据可在此处找到:https://github.com/popovs/400m-cartograms/blob/master/400m_cartograms.R

2 个答案:

答案 0 :(得分:1)

要平行,您可以尝试parapply库中的一些parallel家庭功能。

按照this页面中的步骤,您需要先核对核心数量:

library(parallel)

no_cores <- detectCores() - 1 #it is recomendable that you use the number of cores less one

cl <- makeCluster(no_cores) #initiate cluster
  

导出在并行化过程中使用的所有函数和对象非常重要:

clusterExport(cl, "fishtogram")
clusterExport(cl, "dfname")
clusterExport(cl, "map_years")
...

然后您可以运行lapply的并行版本:

parLapply(cl, seq(1975, 2014, 10), fishtogram)

最后停止群集

stopCluster(cl)

您还可以并行运行代码(foreachforeach库; mclapplyparallel库等等)。

答案 1 :(得分:0)

您的特定错误来自鱼图功能的括号。使用apply时你不需要它们:

apply(seq(1975, 2014, 10), 1, fishtogram)

..会解决这个错误。