如何从嵌套(并行)foreach 循环中获取矩阵数组?
How do you get an array of matrices back from a nested (parallel) foreach loop?
具有独特对象的列表,其中身份很重要(因此顺序......但仅用于跟踪身份):
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)
}
... 和 returns 每对 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)
}
... and returns 三个矩阵的数组,分别表示 'low'、'mid' 和 'high'
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
实际数据是一个很长的list,计算很慢
我怎样才能将此代码与 foreach 和 doParallel 并行化,从而保留数组并保留 row/column 订单(或至少能够跟踪并在结束)?
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 package (v1.0.0)
创建于 2021-06-22
您始终可以 return 索引和结果,稍后重建您的数组。
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]]
具有独特对象的列表,其中身份很重要(因此顺序......但仅用于跟踪身份):
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)
}
... 和 returns 每对 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)
}
... and returns 三个矩阵的数组,分别表示 'low'、'mid' 和 'high'
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
实际数据是一个很长的list,计算很慢
我怎样才能将此代码与 foreach 和 doParallel 并行化,从而保留数组并保留 row/column 订单(或至少能够跟踪并在结束)?
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 package (v1.0.0)
创建于 2021-06-22您始终可以 return 索引和结果,稍后重建您的数组。
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]]