【问题标题】:Repeating a user-defined function using replicate() or sapply()使用 replicate() 或 sapply() 重复用户定义的函数
【发布时间】:2013-01-07 13:12:16
【问题描述】:

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

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()?)。非常感谢

【问题讨论】:

    标签: r sapply replicate


    【解决方案1】:

    就目前而言,您可能有一个具有三个维度的数组。如果你想要一个列表,你会添加 simple=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
    

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

    【讨论】:

    • 非常感谢您的帮助。顺便说一句,关于三维数组,你是对的:)
    【解决方案2】:

    如果将replicate 替换为plyr 包中的rlply,则可以将do.callrbind 一起使用:

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

    如果您不想依赖 plyr 包,您可以随时这样做:

    do.call(rbind, lapply(1:5, function(i) my.fun()))
    

    【讨论】:

      【解决方案3】:

      取决于您用于并行计算的包,但我会这样做(使用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()
      

      【讨论】:

      • 非常感谢,这很有趣,顺便说一下我打算用snowfall
      【解决方案4】:

      试试这个:

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

      你会以矩阵的形式得到'final'的结果。

      【讨论】:

      • 我以为simplify只能接受FALSETRUE"array"。默认的TRUE 在适当的时候返回一个向量或矩阵。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-29
      • 1970-01-01
      相关资源
      最近更新 更多