【问题标题】:How to combine rapply() and mapply(), or how to use mapply/Map recursively?如何组合 rapply() 和 mapply(),或者如何递归使用 mapply/Map?
【发布时间】:2016-06-19 11:56:23
【问题描述】:

我想知道是否有一种简单的方法可以组合rapply( , how = "replace")mapply() 的功能,以便在嵌套列表上递归使用mapply()

例如,我有两个嵌套列表:

A = list(list(c(1,2,3), c(2,3,4)), list(c(4,3,2), c(3,2,1)))
B = list(list(c(1,2,3), c(2,3,4)), list(c(4,3,2), c(3,2,1)))

假设我想将function(x, y) x + y 应用于 A 和 B 中的所有相应元素并保留嵌套结构。期望的结果是

result = list(list(c(2,4,6), c(4,6,8)), list(c(8,6,4), c(6,4,2)))

我认为这应该是rapply(x, f, how = "replace")mapply() 模拟,但不知道如何集成它们。有人可以给我一些指示吗?

另一个快速的问题是,对于密集计算、嵌套列表或多维数组,哪个通常更快?任何 cmets 都非常感谢!

【问题讨论】:

    标签: r multidimensional-array mapreduce nested mapply


    【解决方案1】:

    或者你可以写一个递归函数结合Map来实现,只要A和B的结构相同就可以了:

    s <- function(x, y) tryCatch(x + y, error = function(e) Map(s, x, y))
    s(A, B)
    
    [[1]]
    [[1]][[1]]
    [1] 2 4 6
    
    [[1]][[2]]
    [1] 4 6 8
    
    
    [[2]]
    [[2]][[1]]
    [1] 8 6 4
    
    [[2]][[2]]
    [1] 6 4 2
    

    不确定在这种情况下是否可以使用rapply,它会递归地循环遍历单个列表。但是为了同时递归地遍历两个列表,你需要更高级别的递归吗?我错了吗?

    【讨论】:

    • 非常感谢 Psidom!我意识到这比上述解决方案更简洁、更通用!!
    • 为了避免tryCatch 的开销,替代s 可能是:function(x, y) if(is.atomic(x) &amp;&amp; is.atomic(y)) x + y else Map(s, x, y)
    【解决方案2】:

    您可以递归地(两次)使用Map 来完成此操作:

    Map(function(i, j) Map(function(x, y) x + y, i, j), A, B)
    
    [[1]]
    [[1]][[1]]
    [1] 2 4 6
    
    [[1]][[2]]
    [1] 4 6 8
    
    
    [[2]]
    [[2]][[1]]
    [1] 8 6 4
    
    [[2]][[2]]
    [1] 6 4 2
    

    要使用mapply,您需要simplify=FALSE,但这是Map 的默认值。外部列表元素提供给第一个Map,内部列表元素提供给第二个Map

    【讨论】:

    • 非常感谢海事组织!我想知道你介意演示如何递归地使用 Reduce() 吗?像 Reduce(function(x) Reduce('+', x), A) 这样的东西是一个错误的尝试递归地总结 A 中的向量...
    • 我可以试试@MeredithHu,但这应该作为一个单独的问题提出,因为如下所示,其他人可能会提供一些简洁的解决方案。
    猜你喜欢
    • 2011-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-17
    • 1970-01-01
    相关资源
    最近更新 更多