r语言 - 用NA填充矩阵以满足所需的维数



我有一个矩阵列表,我已经创建。列表中的矩阵具有不同的维数,我想用NA s填充不具有3x3维数的矩阵。

我在下面列出了我的预期结果。我想将其包含在if语句中,如果列表中的矩阵没有3x3维度,我想向这些矩阵添加空列/行,并用NA填充它们。以r为底有没有有效的方法?

# Created Matrices
m1 <- matrix(1:9, 3,3)
m2 <- matrix(1:4, 2,2)
m3 <- matrix(1:3, 3, 1)
# Matrices into a list
l1 <- list(m1, m2, m3)
l1

# Expected Matrices and outputs
m2_new <- matrix(c(1,2,NA,3, 4, rep(NA, 4)), 3,3)
m3_new <- matrix(c(1,2,3,rep(NA, 6)), 3,3)
expected <- list(m1, m2_new, m3_new)

一个选项是创建一个NA matrixreplace的值与'x'基于row/col索引

dummy <- matrix(ncol = 3, nrow = 3)
l2 <- lapply(l1, function(x) replace(dummy, cbind(c(row(x)), c(col(x))), x))

检查

> all.equal(l2, expected)
[1] TRUE

您可以使用矩阵索引替换矩阵的部分。

mat <- array(dim = c(3, 3))
lapply(l1, function(x) `[<-`(mat, 1:nrow(x), 1:ncol(x), x))
# [[1]]
#      [,1] [,2] [,3]
# [1,]    1    4    7
# [2,]    2    5    8
# [3,]    3    6    9
# 
# [[2]]
#      [,1] [,2] [,3]
# [1,]    1    3   NA
# [2,]    2    4   NA
# [3,]   NA   NA   NA
# 
# [[3]]
#      [,1] [,2] [,3]
# [1,]    1   NA   NA
# [2,]    2   NA   NA
# [3,]    3   NA   NA

更新见蔡崇信评论:

n <- 3
l2 <- lapply(l1, function(x) rbind(x, matrix(ncol = ncol(x),                                       nrow = n - nrow(x))))
x  <- sapply(l2, `length<-`, max(lengths(l2)))
list(m1 = matrix(x[,1],3), m2 = matrix(x[,2],3), m3 = matrix(x[,3],3))
$m1
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
$m2
     [,1] [,2] [,3]
[1,]    1    3   NA
[2,]    2    4   NA
[3,]   NA   NA   NA
$m3
     [,1] [,2] [,3]
[1,]    1   NA   NA
[2,]    2   NA   NA
[3,]    3   NA   NA

第一个答案:不正确输出:下面是另一种方法:

x <- t(sapply(l1, `length<-`, max(lengths(l1))))
l2 <- list(x[,1:3], x[,4:6], x[,7:9])
l2
[[1]]
     [,1] [,2] [,3]
[1,]    1    1    1
[2,]    1    2    3
[3,]    1    2    3
[[2]]
     [,1] [,2] [,3]
[1,]    2    2    2
[2,]    4   NA   NA
[3,]   NA   NA   NA
[[3]]
     [,1] [,2] [,3]
[1,]    3    3    3
[2,]   NA   NA   NA
[3,]   NA   NA   NA

我认为有更好的解决方案,但我将处理一个1x1矩阵,这实际上只是一个向量。

你可以在你的代码中使用我在这里做的函数resize_matrix,但是你喜欢。这是相当冗长的,但我认为很容易理解它到底在做什么。注意:该函数将在lapply()调用中使用。

输入:

m1 <- matrix(1:9, 3,3)
m2 <- matrix(1:4, 2,2)
m3 <- matrix(1:3, 3, 1)
m4 <- matrix(1:3, 1, 3)
m5 <- matrix(1, 1, 1)
# Matrices into a list
l1 <- list(m1, m2, m3, m4, m5)
l1
#> [[1]]
#>      [,1] [,2] [,3]
#> [1,]    1    4    7
#> [2,]    2    5    8
#> [3,]    3    6    9
#> 
#> [[2]]
#>      [,1] [,2]
#> [1,]    1    3
#> [2,]    2    4
#> 
#> [[3]]
#>      [,1]
#> [1,]    1
#> [2,]    2
#> [3,]    3
#> 
#> [[4]]
#>      [,1] [,2] [,3]
#> [1,]    1    2    3
#> 
#> [[5]]
#>      [,1]
#> [1,]    1

函数:

resize_matrix <- function(mat, desired_rows = 3, desired_columns = 3){
  needed_cols <- desired_columns - dim(mat)[2]; needed_cols
  needed_rows <- desired_rows - dim(mat)[1]; needed_rows
  if (dim(mat)[1] == 1 & dim(mat)[2] == 1){
    # we're give a matrix with a single value, expand correctly
    final_mat <- matrix(NA, nrow = desired_rows, ncol = desired_columns)
    final_mat[1,1] <- mat
  } else if (needed_cols > 0 & needed_rows > 0){
    # we need to add both rows and columns
    col_res <- rep(NA, needed_rows)
    row_res <- rep(NA, needed_cols)
    mat_temp1 <- rbind(mat, col_res)
    final_mat <- unname(cbind(mat_temp1, row_res))
  } else if (needed_cols > 0 & needed_rows == 0) {
    # we need to add only columns
    row_res <- matrix(rep(NA, needed_cols), 
                      ncol = needed_cols, nrow = desired_rows)
    final_mat <- unname(cbind(mat, row_res))
    
  } else if (needed_cols == 0 & needed_rows > 0) {
    # we need to add only rows
    col_res <- matrix(rep(NA, needed_rows), 
                      ncol = desired_columns, nrow = needed_rows)
    final_mat <- unname(rbind(mat, col_res))
  } else {
    # we don't need to add anything, return the matrix
    final_mat <- mat
  }
 
  return(final_mat)
}

输出:

lapply(l1, FUN = resize_matrix)
#> [[1]]
#>      [,1] [,2] [,3]
#> [1,]    1    4    7
#> [2,]    2    5    8
#> [3,]    3    6    9
#> 
#> [[2]]
#>      [,1] [,2] [,3]
#> [1,]    1    3   NA
#> [2,]    2    4   NA
#> [3,]   NA   NA   NA
#> 
#> [[3]]
#>      [,1] [,2] [,3]
#> [1,]    1   NA   NA
#> [2,]    2   NA   NA
#> [3,]    3   NA   NA
#> 
#> [[4]]
#>      [,1] [,2] [,3]
#> [1,]    1    2    3
#> [2,]   NA   NA   NA
#> [3,]   NA   NA   NA
#> 
#> [[5]]
#>      [,1] [,2] [,3]
#> [1,]    1   NA   NA
#> [2,]   NA   NA   NA
#> [3,]   NA   NA   NA

由reprex包(v2.0.1)于2022-04-16创建

最新更新