使用replicate()或sapply()重复用户定义的函数

Ste*_*rdi 10 r replicate sapply

我定义了一个自定义函数,如下所示:

my.fun = function() {

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

 return(output)

}
Run Code Online (Sandbox Code Playgroud)

返回一个输出矩阵,output由1000行和20列组成.

我需要做的是重复这个函数说5次并将五个output结果存储到一个全新的矩阵中,比如说final,但不使用另一个for循环(这样可以使代码更清晰,也是因为在第二个时刻我我想尝试并行化这些额外的5次重复).

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

我尝试使用final <- replicate(5, my.fun()),正确计算了五个重复,但后来我必须"手动"将元素放入一个全新的5000 x 20矩阵中......有更好的方式吗?(也许用sapply()?).非常感谢

42-*_*42- 14

按照现在的情况,你可能有一个三维数组.如果你想要一个列表,你会添加simplify = FALSE.试试这个:

do.call( rbind, replicate(5, my.fun(), simplify=FALSE ) )
Run Code Online (Sandbox Code Playgroud)

或者您可以aperm在"final"仍然是数组的情况下使用:

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
Run Code Online (Sandbox Code Playgroud)

可能有更经济的矩阵运算.我还没有发现一个.


Dav*_*son 7

如果您要更换replicaterlplyplyr包中,可以使用do.call具有rbind:

library(plyr)
do.call(rbind, rlply(5, my.fun()))
Run Code Online (Sandbox Code Playgroud)

如果您不想依赖plyr包裹,您可以随时:

do.call(rbind, lapply(1:5, function(i) my.fun()))
Run Code Online (Sandbox Code Playgroud)


Rom*_*rik 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()
Run Code Online (Sandbox Code Playgroud)