问题描述
尝试使用并行时,R中的
%dopar%无法正常工作
首先,很抱歉我的英语不好,仅在stackoverflow中,我发现了类似的问题,但无法理解如何处理:(
这是我的原始代码:
library(cramer)
n<-50
theta<-seq(-2,2,0.2)
ks<-rep(0,21)
cvm<-rep(0,21)
ks2<-rep(0,21)
cvm2<-rep(0,21)
for (k in 1:21) {
for (i in 1:5) {
X<-runif(n)
Y<-runif(n,min=0,max=1/(1+theta[k]/sqrt(10)))
ks[k]<-ks[k]+(ks.test(X,Y)$p.value<=0.05)
cvm[k]<-cvm[k]+(cramer.test(X,Y)$p.value<=0.05)
ks2[k]<-ks2[k]+(ks.test(X,Y)$p.value<=0.05)
cvm2[k]<-cvm2[k]+(cramer.test(X,Y)$p.value<=0.05)
}
}
ks<-ks
cvm<-cvm
ks2<-ks2
cvm2<-cvm2
完成后,我们发现值已更改为
> ks
[1] 5 5 5 5 5 4 4 2 0 0 0 0 0 1 3 4 5 5 5 5 5
> cvm
[1] 5 5 5 5 5 4 5 1 2 1 0 1 1 1 2 5 5 5 5 5 5
> ks2
[1] 5 5 5 5 5 4 4 2 0 0 0 0 0 1 3 4 5 5 5 5 5
> cvm2
[1] 5 5 5 5 5 4 5 1 2 1 0 1 1 1 2 5 5 5 5 5 5
为了加快计算速度,我尝试使用foreach,所以我尝试的新代码是:
library("cramer")
library("foreach")
library("doParallel")
n<-50
theta<-seq(-2,21)
cl<-parallel::makeCluster(5,outfile="debug.txt")
doParallel::registerDoParallel(cl)
foreach (k = 1:21,.combine =list,.multicombine = TRUE,.inorder=TRUE,.packages = "cramer") %dopar% {
cat("start to calculate \n",file = paste0("debug_file_",k,".txt"))
for (i in 1:6) {
cat("It's the ","progress","now the runtimes is ",i,"\n",".txt"),append=T)
X<-runif(n)
cat("X is",ks[k],append=T)
Y<-runif(n,Y)$p.value<=0.05)
cat("ks- ","is",append=T)
cvm[k]<-cvm[k]+(cramer.test(X,Y)$p.value<=0.05)
cat("cvm2- ",cvm2[k],append=T)
}
}
ks
cvm
ks2
cvm2
parallel::stopCluster(cl)
通过cpu和调试文件,我猜想calculate parallel可以工作,但是无法正确写入值。
> ks
[1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
> cvm
[1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
> ks2
[1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
> cvm2
[1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
我发现了很多信息,猜测是因为并行将日期复制到了不同的群集中,但是却不知道如何解决我的代码。
我的问题很长,很抱歉
解决方法
ks[k] <- ...
实际上不会在ks
之外修改foreach
变量。修改foreach
,将所有值组合到一个数据框中。
library("cramer")
library("foreach")
library("doParallel")
n <- 50
theta <- seq(-2,2,0.2)
cl <- parallel::makeCluster(5,outfile = "debug.txt")
doParallel::registerDoParallel(cl)
foreach (k = 1:21,.combine = rbind,.multicombine = TRUE,.inorder=TRUE,.packages = "cramer") %dopar% {
ks <- 0
cvm <- 0
ks2 <- 0
cvm2 <- 0
for (i in 1:5) {
X <- runif(n)
Y <- runif(n,min = 0,max = 1 / (1 + theta[k] / sqrt(10)))
ks <- ks + (ks.test(X,Y)$p.value <= 0.05)
cvm <- cvm + (cramer.test(X,Y)$p.value <= 0.05)
ks2 <- ks2 + (ks.test(X,Y)$p.value <= 0.05)
cvm2 <- cvm2 + (cramer.test(X,Y)$p.value <= 0.05)
}
data.frame(
ks = ks,cvm = cvm,ks2 = ks2,cvm2 = cvm2
)
}
#> ks cvm ks2 cvm2
#> 1 5 5 5 5
#> 2 5 5 5 5
#> 3 5 5 5 5
#> 4 5 5 5 5
#> 5 5 5 5 5
#> 6 5 5 5 5
#> 7 3 3 3 3
#> 8 1 1 1 1
#> 9 1 1 1 1
#> 10 0 1 0 1
#> 11 2 0 2 0
#> 12 1 3 1 3
#> 13 0 0 0 0
#> 14 1 1 1 1
#> 15 2 3 2 3
#> 16 3 3 3 3
#> 17 4 4 4 4
#> 18 3 3 3 3
#> 19 4 4 4 4
#> 20 5 5 5 5
#> 21 5 5 5 5
parallel::stopCluster(cl)