【问题标题】:make .combine function scaleable使 .combine 函数可缩放
【发布时间】:2023-03-19 22:12:01
【问题描述】:

我正在尝试使用 foreach,但在使 .combine 函数可扩展时遇到了问题。例如,这里是一个简单的组合函数

MyComb <- function(part1,part2){
          xs <- c(part1$x,part2$x)
          ys <- c(part1$y,part2$y)
          return(list(xs,ys))
          }

当我使用此函数将 foreach 语句与 2 以外的迭代器组合时,它会错误地返回它。例如这有效:

   x = foreach(i=1:2,.combine=MyComb) %dopar% list("x"=i*2,"y"=i*3)

但不是这个:

 x = foreach(i=1:3,.combine=MyComb) %dopar% list("x"=i*2,"y"=i*3)

有没有一种方法可以泛化 combine 函数以使其可扩展到 n 次迭代?

【问题讨论】:

    标签: r foreach domc


    【解决方案1】:

    您的.combine 函数必须采用两个部分并返回“看起来”像一个部分的东西(可以作为一部分传回)或接受多个参数并将它们一次放在一起(具有相同的限制)。因此,至少您的MyComb 必须返回一个包含xy 组件的列表(这是您的%dopar% 的每一部分所做的。

    有几种方法可以做到这一点:

    MyComb1 <- function(part1, part2) {
        list(x=c(part1$x, part2$x), y=c(part1$y, part2$y))
    }
    
    x = foreach(i=1:3,.combine=MyComb1) %dopar% list("x"=i*2,"y"=i*3)
    

    这个版本一次只需要两块。

    MyComb2 <- function(...) {
        dots = list(...)
        ret <- lapply(names(dots[[1]]), function(e) {
            unlist(sapply(dots, '[[', e))
        })
        names(ret) <- names(dots[[1]])
        ret
    }
    
    s = foreach(i=1:3,.combine=MyComb2) %dopar% list("x"=i*2,"y"=i*3)
    x = foreach(i=1:3,.combine=MyComb2, .multicombine=TRUE) %dopar% list("x"=i*2,"y"=i*3)
    

    这个可以一次取多块并将它们组合起来。它更通用(但更复杂)。

    【讨论】:

    • 谢谢!所以在我的实际应用程序中,提供给 MyComb 的每个位都是一个列表,其中包含一堆元素,每个元素都是矩阵。我想从原始列表中 abind(...,along=3) 每个同名矩阵,最后返回一个包含这些数组的大列表。我无法看到如何使用您的 MyComb2 解决方案来做到这一点。有什么想法吗?
    • @scottyaz 可能只是将unlist(...) 替换为abind(...,along=3),但如果没有构建一个工作示例,我不确定。 sapply(dots, '[[', e) 的结果是每个部分的名称为“e”的组件列表。 abind 可以将列表作为其参数,因此它应该与从 sapply 返回的内容一起使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-14
    • 2020-11-29
    相关资源
    最近更新 更多