【问题标题】:Function not found in R doParallel 'foreach' - Error in { : task 1 failed - "could not find function "raster""在 R doParallel 'foreach' 中找不到函数 - { 中的错误:任务 1 失败 -“找不到函数“光栅””
【发布时间】:2013-12-20 13:03:46
【问题描述】:

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

以下代码返回错误:

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""

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)
}

这次没有找到 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)
    }
  }
})

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

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

【问题讨论】:

  • 尝试使用foreach.packages参数。包没有加载到工人身上。
  • cran.r-project.org/web/packages/foreach/vignettes/foreach.pdf 第 8 页和第 9 页。或 ?foreach。这就是罗兰评论中给出的信息。
  • 非常感谢您的帮助!这个问题解决了,但现在我有一个新问题。我将编辑我原来的问题。
  • 请不要更改您的问题以提出新问题。这将使未来的访客感到困惑。如果您有新问题,请提出新问题。这显然是一个新问题。另请参阅 stackoverflow.com/tourstackoverflow.com/help/asking 了解该网站的工作原理
  • 我只是想建立在以前的响应者已经拥有的关于我的代码的知识库的基础上。

标签: r


【解决方案1】:

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

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

更多解释

foreach 包在幕后做了很多设置。会发生以下情况(原则上,技术细节稍微复杂一些):

  • foreach 设置了一个“worker”系统,您可以将其视为单独的 R 会话,每个会话都提交到集群中的不同核心。

  • 需要执行的功能与执行功能所需的对象一起加载到每个“工人”会话中

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

  • 将不同工作人员的计算结果放在一起并在“主”R 会话中报告。

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


请注意,当您使用其他包(例如 parallelsnowfall)时,您必须明确设置这些工作程序,并注意在工作程序会话上传递对象和加载包。

【讨论】:

  • 还必须加载所有依赖项。
【解决方案2】:

我处理了同样的问题。我的解决方案是

  1. 在单独的 R 文件中准备函数。

函数.R

f <- function(parameters...){Body...}
  1. 在 foreach 循环中获取您的函数

MainFile.R

library(foreach)
library(doParallel)
cores=detectCores()
cl <- makeCluster(cores[1]-2) #not to overload your computer
registerDoParallel(cl)

clusterEvalQ(cl, .libPaths("C:/R/win-library/4.0")) #Give your R library path
output <- foreach(i=1:5, .combine = rbind) %dopar% {
source("~/Function.R") # That is the main point. Source your Function File here.
temp <- f(parameters...) # use your custom function after sourcing 
temp
}

stopCluster(cl)

【讨论】:

    【解决方案3】:

    我在使用 foreach 时也遇到了“找不到函数”错误。通常,此问题与 foreach 工人无法使用的包中的功能有关。但是我的用例是在与foreach 相同的脚本中定义的非包/自定义/孤立(?)/未导出(?)函数。这是一个肮脏的快速修复,而不是创建一个新包并导出函数。这是场景:

    单个脚本:

    funA(){
        ...
    }
    
    funB(){
        ...
    }
    
    funC(){     
        foreach(){
            funA(); funB()
        }
    }
    
    funC()
    

    funC 之前定义了两个函数funAfunB,然后调用了funC。看起来前两个在funC 的全局环境中没有被考虑,即使它们在同一个脚本中,因此错误。简单的解决方案是将funAfunB 剪切并粘贴到funC 定义的顶部,如下所示:

    funC(){
        funA(){
            ...
        }
        funB(){
            ...
        }       
        foreach(){}
    }
    
    funC()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-11
      • 2019-07-08
      • 1970-01-01
      • 2018-02-05
      • 2021-09-09
      • 1970-01-01
      • 2020-03-15
      相关资源
      最近更新 更多