在R doParallel'foreach'中找不到的函数 - {:task 1 failed - "找不到函数"raster""出错

Kar*_*ren 36 r

我试图在我的机构第一次使用高性能集群,我遇到了一个我无法解决的问题.

以下代码返回错误:

ptime<-system.time({
  r <- foreach(z = 1:length(files),.combine=cbind) %dopar% {
    raster <- raster(paste(folder,files[1],sep=""))
    data<-getValues(raster)
    clp <- na.omit(data)
    for(i in 1:length(classes)){
      results[i,z]<-length(clp[clp==classes[i]])/length(clp)
      print(z)
    }
  }
})

Error in { : task 1 failed - "could not find function "raster""
Run Code Online (Sandbox Code Playgroud)

A还为我的另一项任务尝试了不同的foreach代码:

r <- foreach (i=1:length(poly)) %dopar% {
  clip<-gIntersection(paths,poly[i,])
  lgth<-gLength(clip)
  vid<-poly@data[i,3]
  path.lgth[i,] <- c(vid,lgth)
  print(i)
}
Run Code Online (Sandbox Code Playgroud)

这次没有找到gIntersection函数.显然,这些包都已安装和加载.阅读一些论坛帖子后,它似乎与功能执行/操作的环境有关.

有人可以帮忙吗?我不是程序员!

谢谢!

更新:

我已经调整了我提供的解决方案的代码:

results<-matrix(nrow=length(classes),ncol=length(files))
dimnames(results)[[1]]<-classes
dimnames(results)[[2]]<-files

ptime<-system.time({
    foreach(z = 1:length(files),.packages="raster") %dopar% {
    raster <- raster(paste(folder,files[z],sep=""))
    data<-getValues(raster)
    clp <- na.omit(data)
    for(i in 1:length(classes)){
      results[i,z]<-length(clp[clp==classes[i]])/length(clp)
      print(z)
    }
  }
})
Run Code Online (Sandbox Code Playgroud)

但我得到的是输出(我的结果矩阵)充满了na的.正如您所看到的,我创建了一个名为results的矩阵对象来填充结果(适用于for循环),但在阅读foreach的文档后,您似乎可以使用此函数以不同方式保存结果.

关于我应该为.combine论证选择什么的建议?

Jor*_*eys 59

foreach小插图和foreach的帮助页面中,.packages指出了在使用并行计算时默认未加载的函数时必须提供的参数.所以第一个例子中的代码应该是:

ptime<-system.time({
  r <- foreach(z = 1:length(files),
               .combine=cbind, 
               .packages='raster') %dopar% {
      # some code
      # and more code
  }
})
Run Code Online (Sandbox Code Playgroud)

更多解释

foreach软件包在幕后进行了很多设置.会发生什么是以下(原则上,技术细节有点复杂):

  • foreach 建立一个"工作者"系统,您可以将其视为单独的R会话,每个会话都会提交到群集中的不同核心.

  • 需要执行的功能被加载到每个"工作"会话中,以及执行该功能所需的对象

  • 每个工作人员计算数据子集的结果

  • 将不同工人的计算结果放在一起并在"主"R会议中报告.

由于工作人员可以被视为单独的R会话,因此"主"会话中的包不会自动加载.您必须指定应在这些工作程序会话中加载哪些程序包,这就是所使用的.package参数foreach.


请注意,当您使用其他包(例如parallelsnowfall)时,您必须显式设置这些工作程序,并且还要负责在工作会话中传递对象和加载包.

  • 还必须加载所有依赖项. (3认同)