两个(或更多)嵌套矩阵列表的逐元素平均值

element-wise averages of two (or more) nested lists of matrices

我有两个列表 A_1A_2,每个列表包含两个矩阵。

A_1 <- list(a=matrix(1:8, 2), b=matrix(2:9, 2))

A_2 <- list(a=matrix(10:17, 2), b=matrix(5:12, 2))

我想计算这两个列表的逐元素平均值,结果列表为

tibble::lst((A_1$a + A_2$a)/2, (A_1$b + A_2$b)/2)

我用过

purrr::pmap(list(A_1 , A_2), mean)

但是得到了

Error in mean.default(.l[[1L]][[i]], .l[[2L]][[i]], ...) : 
  'trim' must be numeric of length one`  

purrr::map2(A_1, A_2, mean)

Error in mean.default(.x[[i]], .y[[i]], ...) : 
  'trim' must be numeric of length one`

在基数 R 中:

item_names  <- names(A_1)

structure(
    lapply(item_names, function(name){
        0.5 * (A_1[[name]] + A_2[[name]])
        ## or, if you want the scalar mean:
        ## mean(A_1[[name]] + A_2[[name]])
    }),
    names = item_names
)


#> $a
#>      [,1] [,2] [,3] [,4]
#> [1,]  5.5  7.5  9.5 11.5
#> [2,]  6.5  8.5 10.5 12.5
#> 
#> $b
#>      [,1] [,2] [,3] [,4]
#> [1,]  3.5  5.5  7.5  9.5
#> [2,]  4.5  6.5  8.5 10.5

你的错误在于使用第二个矩阵作为 meantrim= 参数,这是第二个。您需要 c 连接矩阵。 示例:

mean(1:3, 2:4)
# Error in mean.default(1:3, 2:4) : 'trim' must be numeric of length one

mean(c(1:3, 2:4))
# [1] 2.5

作为解决方案,您可以使用 Map

Map(\(x, y) (x + y)/2, A_1, A_2)
# $a
#      [,1] [,2] [,3] [,4]
# [1,]  5.5  7.5  9.5 11.5
# [2,]  6.5  8.5 10.5 12.5
# 
# $b
#      [,1] [,2] [,3] [,4]
# [1,]  3.5  5.5  7.5  9.5
# [2,]  4.5  6.5  8.5 10.5

或者,为什么不使用数组?

AA_1 <- array(unlist(A_1), dim=c(dim(A_1$a), length(A_1)))
AA_2 <- array(unlist(A_2), dim=c(dim(A_2$a), length(A_2)))

(AA_1 + AA_2)/2
# , , 1
# 
#      [,1] [,2] [,3] [,4]
# [1,]  5.5  7.5  9.5 11.5
# [2,]  6.5  8.5 10.5 12.5
# 
# , , 2
# 
#      [,1] [,2] [,3] [,4]
# [1,]  3.5  5.5  7.5  9.5
# [2,]  4.5  6.5  8.5 10.5

在基础 R 中,我们可以使用:

A <-list(A_1, A_2)
lapply(Reduce(\(x, y)Map('+', x, y), A), '/', length(A))

$a
     [,1] [,2] [,3] [,4]
[1,]  5.5  7.5  9.5 11.5
[2,]  6.5  8.5 10.5 12.5

$b
     [,1] [,2] [,3] [,4]
[1,]  3.5  5.5  7.5  9.5
[2,]  4.5  6.5  8.5 10.5

这段代码是通用的,因为我们可以用它来计算多个列表的平均值。 请注意,A_1A_2 必须具有相同数量的矩阵,不一定是 2。可以是 10 等。还要注意每个对应的矩阵具有相同的维度。示例如下:

B_1 <- list(matrix(c(1,2,3,4), 2), matrix(c(1,3,4,2), 2),
            matrix(c(1:10), 5), matrix(c(1:20), 5))
B_2 <- lapply(B_1, '*', 2) # In this case, its B_1 * 2
B_3 <- lapply(B_2, '*', 3) #

现在您可以使用上面提供的代码了:

B <-list(B_1, B_2, B_3)
lapply(Reduce(\(x, y)Map('+', x, y), B), '/', length(B))