1

使用唯一对象列表,其中身份很重要(因此排序......但仅用于跟踪身份):

fakeDataList <- list(one = 1,
                     two = 2,
                     three = 3,
                     four = 4)

有一个执行成对计算的函数......

fakeInnerFxn <- function(l){
  x <- l[[1]]
  y <- l[[2]]
  low <- x + y - 1
  mid <- x + y
  high <- x + y + 1
  out <- c(low, mid, high)
  return(out)
}

...并为每对 id 返回三个值

fakeInnerFxn(fakeDataList[c(1,2)])
#> [1] 2 3 4

内部函数嵌套在外部函数中,外部函数对完整列表执行每个成对操作......

fakeOuterFxn <- function(d){
  n <- length(d)
  out <- array(0, dim = c(n,n,3))
  colnames(out) <- names(d)
  rownames(out) <- names(d)
  for(i in 1:n){
    for(j in (i+1):n){
      if (j <= n) {
        out[i, j, ] <- fakeInnerFxn(d[c(i, j)])
      }
    }
  }
 diag(out[,,1]) <- 0  # not sure how to do this succinctly 
 diag(out[,,2]) <- 0   
 diag(out[,,3]) <- 0   
 
 return(out)
}

...并返回代表“低”、“中”和“高”的三个矩阵的数组

fakeOuterFxn(fakeDataList)
#> , , 1
#> 
#>       one two three four
#> one     0   2     3    4
#> two     0   0     4    5
#> three   0   0     0    6
#> four    0   0     0    0
#> 
#> , , 2
#> 
#>       one two three four
#> one     0   3     4    5
#> two     0   0     5    6
#> three   0   0     0    7
#> four    0   0     0    0
#> 
#> , , 3
#> 
#>       one two three four
#> one     0   4     5    6
#> two     0   0     6    7
#> three   0   0     0    8
#> four    0   0     0    0

实际数据是一个很长的列表,计算速度很慢。

我如何才能将此代码与 foreach 和 doParallel 并行化,以保留数组并保留行/列顺序(或至少能够在最后跟踪和重新排序)?

library(foreach)
library(doParallel)
#> Loading required package: iterators
#> Loading required package: parallel

registerDoParallel(detectCores()-2)  

for 循环不需要在函数内部,但如果是的话,它会很整洁。

d <- fakeDataList
n <- length(d)

据我所知,这真的是:

out <- foreach(i=1:n, .combine = 'c') %:%
  foreach(j=(i+1):n, .combine = 'c') %dopar% {
    if (j <= n) {
      fakeInnerFxn(d[c(i, j)])
    }
  }

答案都在这里,但是我该如何取回一个数组呢?

out
#>  [1] 2 3 4 3 4 5 4 5 6 4 5 6 5 6 7 6 7 8 7 8 9

reprex 包(v1.0.0)于 2021-06-22 创建

4

1 回答 1

1

您始终可以返回带有结果的索引并稍后重建您的数组。

res <- foreach(i=1:(n-1), .combine = 'c') %:%
  foreach(j=(i+1):n) %dopar% {
    list(i, j, fakeInnerFxn(d[c(i, j)]))
  }

n <- length(d)
out <- array(0, dim = c(n, n, 3))
for (res_k in res) out[res_k[[1]], res_k[[2]], ] <- res_k[[3]]
于 2021-06-23T06:30:34.567 回答