如何在第一个嵌套foreach循环中访问迭代计数器?

14ifxucb  于 2023-05-20  发布在  其他
关注(0)|答案(1)|浏览(148)

我试图运行一个代码,以填补一个大矩阵较小的子矩阵使用并行计算。但我得到这个错误消息:

Error in foreach(i = j:K, .combine = "c", .packages = "geosphere", .options.snow = list(progress = iteration_progress),  :    object 'j' not found

代码如下:

library(bigmemory)
library(parallel)
library(doSNOW)

## Create a dataset
N = 100
data <- data.frame(long = runif(N, min = -130, max = -60), lat = runif(N, min = 16, max = 60))
## head(data)

cutBySize <- function(m, blockSize, nb = ceiling(m / blockSize)) {
  int <- m / nb
  upper <- round(1:nb * int)
  lower <- c(1, upper[-nb] + 1)
  size <- c(upper[1], diff(upper))
  cbind(lower, upper, size)
}

index_sequence <- function(limits) {
  seq(limits[1], limits[2])
}

## Create the big matrix
n <- nrow(data)
mat <- big.matrix(n, n, backingfile = "test_1.bk", descriptorfile = "test_1.desc")

## Create the intervals
intervals <- cutBySize(n, blockSize = 5)
K <- nrow(intervals)

## Fill the big matrix by small submatrices
cl <- makeCluster(detectCores() - 2, outfile = "")
registerDoSNOW(cl)
iteration_progress <- function(n){cat(sprintf("Task %d out of %d completed\n", n, K))}

test <- foreach(j = 1:K, .combine = 'c') %:%
  foreach(i = j:K, .combine = 'c', .packages = "geosphere", .options.snow = list(progress = iteration_progress), .errorhandling = "pass") %dopar% {
    block_j <- index_sequence(intervals[j, ])
    block_i <- index_sequence(intervals[i, ])
    tmp <- geosphere::distm(data[block_i, c('long', 'lat')], data[block_j, c('long', 'lat')])
    mat[block_i, block_j] <- tmp
    mat[block_j, block_i] <- t(tmp)
  }
stopCluster(cl)

那么,我如何在第一个嵌套循环中访问迭代计数器呢?我发现这篇文章How do I access counter in a nested foreach loop?,但这并不能解决我的问题。任何建议将不胜感激。

gpnt7bae

gpnt7bae1#

这似乎是由foreach包中的一个bug引起的。我有reported it,并提出了一个修复程序,您可以使用remotes::install_github("RevolutionAnalytics/foreach#42")安装。

相关问题