我已经定义了一个自定义函数,如下所示:
my.fun = function() {
for (i in 1:1000) {
...
for (j in 1:20) {
...
}
}
return(output)
}
返回输出矩阵output
,由1000行和20列组成。
我需要做的是重复该功能5次,并将5个output
结果存储到一个全新的矩阵中,比如说final
,但是而不使用另一个for循环(这是为了使代码更清晰,也是因为在第二时刻我想尝试并行化这些额外的5次重复)。
因此final
应该是一个包含5000行和20列的矩阵(这5次重复的基本原理是在我使用的两个for循环中,其中包括sample
)。
我尝试使用final <- replicate(5, my.fun())
,这正确地计算了五个复制品,但后来我必须“手动”将这些元素放入一个全新的5000 x 20矩阵中......是否有一种更为优雅的方式? (也许使用sapply()
?)。非常感谢
答案 0 :(得分:14)
现在你可能有一个三维数组。如果你想要一个列表,你会添加simplify = FALSE。试试这个:
do.call( rbind, replicate(5, my.fun(), simplify=FALSE ) )
或者,在“final”仍然是数组的情况下,您可以使用aperm
:
fun <- function() matrix(1:10, 2,5)
final <- replicate( 2, fun() )
> final
, , 1
[,1] [,2] [,3] [,4] [,5]
[1,] 1 3 5 7 9
[2,] 2 4 6 8 10
, , 2
[,1] [,2] [,3] [,4] [,5]
[1,] 1 3 5 7 9
[2,] 2 4 6 8 10
> t( matrix(aperm(final, c(2,1,3)), 5,4) )
[,1] [,2] [,3] [,4] [,5]
[1,] 1 3 5 7 9
[2,] 2 4 6 8 10
[3,] 1 3 5 7 9
[4,] 2 4 6 8 10
可能有更经济的矩阵运算。我还没有发现一个。
答案 1 :(得分:7)
如果您使用replicate
包中的plyr
替换do.call
,则可以rbind
使用library(plyr)
do.call(rbind, rlply(5, my.fun()))
:
plyr
如果您不想依赖do.call(rbind, lapply(1:5, function(i) my.fun()))
包,则可以随时执行:
{{1}}
答案 2 :(得分:7)
取决于您用于并行计算的程序包,但这是我将如何操作(使用sapply
将其隐藏在循环中,就像replicate
)。
library(snowfall)
sfInit(parallel = TRUE, cpus = 4, type = "SOCK")
# sfExport() #export appropriate objects that will be needed inside a function, if applicable
# sfLibrary() #call to any special library
out <- sfSapply(1:5, fun = my.fun, simplify = FALSE)
sfStop()
答案 3 :(得分:0)
试试这个:
final <- replicate(5, my.fun(), simplify = "matrix")
您将获得最终结果&#39;以矩阵的形式。