如何结合rapply()和mapply(),或如何递归使用mapply/Map?

4
我想知道是否有一种简单的方法来将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() 类比,但我无法想出如何将它们集成起来。请问有人能够给我一些指导吗?
另一个快速问题是,对于密集计算,嵌套列表和多维数组哪个通常更快?非常感谢任何意见!
2个回答

4

或者你可以编写一个递归函数,结合 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!我意识到这个方法很好,比上面的解决方案更通用!! - shenglih
1
为了避免 tryCatch 的开销,另一种选择是:function(x, y) if(is.atomic(x) && is.atomic(y)) x + y else Map(s, x, y) - alexis_laz

1
你可以递归地(两次)使用 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

非常感谢你,Imo!我在想你是否介意演示如何递归使用Reduce()函数?例如像这样的Reduce(function(x) Reduce('+', x), A),它是一个有缺陷的尝试来递归地对A中的向量求和... - shenglih
我可以尝试一下,@MeredithHu,但这应该作为一个单独的问题提出,因为像下面这样,其他人可能会提供一些不错的解决方案。 - lmo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接