我第一次尝试在我的机构使用高性能群集,而我遇到了一个无法解决的问题。
以下代码返回错误:
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参数选择什么的建议?
答案 0 :(得分:57)
在foreach的vignette of foreach和帮助页面中,指出参数.packages
是必要的,以便在使用默认情况下未加载的函数进行并行计算时提供。所以第一个例子中的代码应该是:
ptime<-system.time({
r <- foreach(z = 1:length(files),
.combine=cbind,
.packages='raster') %dopar% {
# some code
# and more code
}
})
更多解释
foreach
包在幕后进行了很多设置。会发生什么是以下(原则上,技术细节有点复杂):
foreach
建立了一个&#34;工人&#34;您可以将其视为单独的R会话,每个会话都会提交到群集中的不同核心。
需要执行的功能被加载到每个&#34; worker&#34;会话,以及执行功能所需的对象
每个工作人员计算数据子集的结果
将不同工人的计算结果放在一起并在&#34; master&#34; R session。
由于工作人员可被视为单独的R会议,来自&#34; master&#34;会话不会自动加载。您必须指定应在这些工作会话中加载哪些软件包,以及.package
foreach
的{{1}}参数的用途。
请注意,当您使用其他软件包(例如parallel
或snowfall
)时,您必须明确设置这些工作程序,并且还要处理传递对象和加载软件包的问题。工人会议。
答案 1 :(得分:2)
我处理了同样的问题。我的解决办法是
Function.R
f <- function(parameters...){Body...}
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)