具有 NA 的矩阵求和列表

问题描述 投票:0回答:2

我想计算矩阵的总和并忽略包含的任何 NA,如以下示例所示:

x1 <- matrix(c(NA,NA,2,2),2,2)
x2 <- matrix(c(NA,3,NA,NA),2,2)
x3 <- matrix(c(NA,NA,NA,NA),2,2)
x4 <- matrix(c(1,2,3,4),2,2)
lx <- list(x1,x2,x3,x4)
Reduce('+',lx) # does not work because of NAs

result <- matrix(c(1,5,5,6),2,2)

所以结果应该是:

      [,1] [,2]
[1,]    1    5
[2,]    5    6

这怎么办?

r matrix
2个回答
4
投票

我们可以编写一个自定义函数并在

Reduce
中使用它。我们将
NA
替换为 0,然后添加它们。

modifiedSum <- function(x, y) {
  replace(x, is.na(x), 0) + replace(y, is.na(y), 0)
}

Reduce(modifiedSum, lx)

#     [,1] [,2]
#[1,]    1    5
#[2,]    5    6

0
投票

我希望有一个基本的 R 方法可以做到这一点,但显然没有。不过,有一点需要澄清:对于我的用例,重要的是,如果所有矩阵在同一位置都有 NA,则结果是 NA,而不是 0(就像我见过的几乎所有其他解决方案一样)。这是一个处理此细节的自定义函数:

add_mx_na <- function(mx1, mx2) {
  n_row <- nrow(mx1)
  n_col <- ncol(mx1)
  result <- matrix(nrow = n_row, ncol = n_col)
  
  for (i.r in 1:n_row) {
    for (i.c in 1:n_col) {
      if (is.na(mx1[i.r, i.c])) {
        # If mx1 is NA, then if mx2 is also NA, then the result is NA; otherwise it is just mx2
        result[i.r, i.c] <- mx2[i.r, i.c]
      } else if (is.na(mx2[i.r, i.c])) {
        result[i.r, i.c] <- mx1[i.r, i.c]
      } else {
        result[i.r, i.c] <- mx1[i.r, i.c] + mx2[i.r, i.c]
      }
    }
  }
  
  return(result)
}

(x1 <- matrix(c(NA,NA,2,2),2,2))
#>      [,1] [,2]
#> [1,]   NA    2
#> [2,]   NA    2
(x2 <- matrix(c(NA,3,NA,NA),2,2))
#>      [,1] [,2]
#> [1,]   NA   NA
#> [2,]    3   NA
(x3 <- matrix(c(NA,NA,NA,NA),2,2))
#>      [,1] [,2]
#> [1,]   NA   NA
#> [2,]   NA   NA
(x4 <- matrix(c(1,2,3,4),2,2))
#>      [,1] [,2]
#> [1,]    1    3
#> [2,]    2    4


add_mx_na(x1, x2)
#>      [,1] [,2]
#> [1,]   NA    2
#> [2,]    3    2
add_mx_na(x1, x3)
#>      [,1] [,2]
#> [1,]   NA    2
#> [2,]   NA    2
add_mx_na(x1, x4)
#>      [,1] [,2]
#> [1,]    1    5
#> [2,]    2    6

创建于 2024-09-04,使用 reprex v2.1.1

要一次对多个矩阵求和,我们可以使用

Reduce()
函数并将矩阵捆绑到一个列表中:

Reduce(add_mx_na, list(x1, x2, x3))
#>      [,1] [,2]
#> [1,]   NA    2
#> [2,]    3    2
© www.soinside.com 2019 - 2024. All rights reserved.