2013-01-23 20 views
9

我已经定义的自定义功能,这样的功能或(:重复一个用户定义的使用复制()sapply)

my.fun = function() { 

     for (i in 1:1000) { 
     ... 
     for (j in 1:20) { 
      ... 
     } 
     } 

return(output) 

} 

它返回一个输出矩阵,output,通过1000行和20列组成。

我需要做的就是重复功能,比如5倍,并存储五个output结果到一个全新的矩阵,说final,但不使用其他for循环(此为使代码更清晰,也因为在第二时刻,我想尝试并行化这些额外的5次重复)。

因此final应该是一个具有5000行和20列的矩阵(这5次重复的原理是在我使用的两个for循环中,其他函数sample)。

我试图使用final <- replicate(5, my.fun()),它正确地计算了五个重复,但是我必须“手动”将元素放入一个全新的5000 x 20矩阵中。是否有更加优雅的方法可以这样做? (可能使用sapply()?)。非常感谢

回答

11

正如你所看到的,你可能有一个三维数组。如果你想有一个列表,你可以添加一个简化= FALSE。试试这个:

do.call(rbind, replicate(5, my.fun(), simplify=FALSE)) 

或者你也可以在“最后”仍是一个数组的情况下使用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 

有可能是更经济的矩阵运算。我还没有发现。

+0

非常感谢您的帮助。顺便说一下,关于三维阵列,你是对的:) – Stezzo

7

如果你rlplyplyr包取代replicate,您可以使用do.callrbind

library(plyr) 
do.call(rbind, rlply(5, my.fun())) 

如果你不想靠plyr包,你总是可以做:

do.call(rbind, lapply(1:5, function(i) my.fun())) 
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() 
+0

非常感谢,这是非常有趣的,顺便说一下,我打算使用'降雪'。 – Stezzo

0

试试这个:

final <- replicate(5, my.fun(), simplify = "matrix") 

你会得到 '最终' 结果在矩阵的形式。