foreach(并行)用于 R 中的矩阵运算

foreach (parallel) for matrix operation in R

我正在尝试将以下 for 循环转换为 foreach 以利用并行。

dt = data.frame(t(data.frame(a=sample(1:10,10), b=sample(1:10,10), c=sample(1:10,10), d=sample(1:10,10))))

X = as.matrix(dt)
c = ncol(X)
itemnames=names(dt)

sm=matrix(0,c,c)
colnames(sm)=itemnames
row.names(sm)=itemnames
for (j in 1:c){
  ind=setdiff(1:c,j)
  print(ind)
  print(j)
  sm[j,ind]=sign(X[j]-X[ind])
  print(sm[j,ind])
}

cvec = 1:c

r = foreach(d = cvec, .combine = rbind) %dopar% {
  ind = setdiff(1:10,d)
  sm[d,ind]=sign(X[d]-X[ind])
  }

使用 for 循环,我得到 10*10 矩阵,其中上述符号函数替换了非对角线元素,对角线元素为 0。 但是对于 foreach,我得到 10*9 矩阵,它缺少对角线元素,其他一切都相同。 请帮助我获得与 for 循环相同的输出。提前致谢。

我不确定你想在这里实现什么,因为你只使用了矩阵的前十个元素。这可以在没有任何循环的情况下完成:

sign(outer(X[1:10], X[1:10], FUN = "-"))

此外,我不确定对于此类问题并行处理会更快,即使假设实际情况要大得多。但是如果你想使用 foreach,你不应该在循环中分配给全局 sm,而是 return 最后一个合适的向量:

foreach(d = cvec, .combine = rbind) %dopar% {
  ind <- setdiff(cvec,d)
  res <- rep(0, 10)
  res[ind] <- sign(X[d]-X[ind])
  res
}

如果要并行分配给矩阵,则需要共享矩阵:

# devtools::install_github("privefl/bigstatsr")
library(bigstatsr)
sm <- FBM(c, c)

library(foreach)
cl <- parallel::makeCluster(3)
doParallel::registerDoParallel(cl)
r = foreach(d = cvec, .combine = c) %dopar% {
  ind = setdiff(1:10,d)
  sm[d,ind]=sign(X[d]-X[ind])
  NULL
}
parallel::stopCluster(cl)

sm[]