在Windows机器上使用R,我目前在3D阵列(720x360x1368)上运行嵌套循环,循环通过d1和d2以在d3上应用函数并将输出组合到具有类似维度的新数组。
在下面的可重复示例中,我将维度减少了10倍,以使执行更快。
library(SPEI)
old.array = array(abs(rnorm(50)), dim=c(72,36,136))
new.array = array(dim=c(72,36,136))
for (i in 1:72) {
for (j in 1:36) {
new.listoflists <- spi(ts(old.array[i,j,], freq=12, start=c(1901,1)), 1, na.rm = T)
new.array[i,j,] = new.listoflists$fitted
}
}
其中spi()是SPEI包中的函数,返回列表列表,其中每个循环增量使用一个长度为1368的特定列表$fitted
来构造新数组。
虽然这个循环完美无缺,但计算需要相当长的时间。我已经读过foreach
可用于并行化for
循环。
但是,我不明白如何实现新阵列的嵌套和组装,以使旧阵列和新阵列的dimnames保持一致。
(最后,我希望能够使用as.data.frame.table()
将旧数组和新数组转换为“平面”长面板数据框,并将它们合并在一起尺寸。)
有关如何使用并行计算实现所需输出的任何帮助都将受到高度赞赏!
干杯
CubicTom
答案 0 :(得分:0)
通过可重复的示例本来会更好,这是我想出的:
首先创建要使用的群集
cl <- makeCluster(6, type = "SOCK")
registerDoSNOW(cl)
然后创建循环并关闭集群:
zz <- foreach(i = 1:720, .combine = c) %:%
foreach(j = 1:360, .combine = c ) %dopar% {
new.listoflists <- FUN(old.array[i,j,])
new.array[i,j,] <- new.listoflists$list
}
stopCluster(cl)
这将创建一个列表zz,其中包含new.array [i,j,]的每次迭代,然后您可以将它们绑定在一起:
new.obj <- plyr::ldply(zz, data.frame)
希望这能帮到你!
答案 1 :(得分:0)
我没有使用与你的问题一样多的维度,因为我想确保行为是正确的。 所以在这里我使用带有多个参数的mapply。结果是结果列表。然后我用matrix()包装它以获得你希望的尺寸。 请注意,使用次重复 i ,并使用每次重复 j 。这是至关重要的,因为matrix()先按行放入条目,然后在达到行数时换行到下一列。
new.array = array(1:(5*10*4), dim=c(5,10,4))
# FUN: function which returns lists of
FUN <- function(x){
list(lapply(x, rep, times=3))
}
# result of the computation
result <- matrix(
mapply(
function(i,j,...){
FUN(new.array[i,j,])
}
,i = rep(1:nrow(new.array),times=ncol(new.array))
,j = rep(1:ncol(new.array),each=nrow(new.array))
,new.array=new.array
)
,nrow=nrow(new.array)
,ncol=ncol(new.array)
)