使用 R 中的向量创建并填充上三角矩阵

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

我需要基于不同长度的向量创建一个方阵,其中向量的索引仅填充上三角形,而不回收向量元素。

我尝试了以下 R 代码:

# example vector (could be longer or shorter!)
v <- letters[1:8]
# calculate dimensions of square matrix
n <- ceiling((-1 + sqrt(1 + 8 * length(v))) / 2)
# create empty matrix
m <- matrix(NA, nrow=n, ncol=n)
# populate the matrix
m[lower.tri(m, diag=TRUE)] <- 1:length(v)
m <- t(m)

生成的矩阵如下所示:

     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]   NA    5    6    7
[3,]   NA   NA    8    1
[4,]   NA   NA   NA    2

如何以仅填充上三角部分而不需要回收向量索引元素的方式填充矩阵?

     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]   NA   NA    5    6
[3,]   NA   NA   NA    7
[4,]   NA   NA   NA    8
  • 矢量元素不回收
  • 使用方阵的完整维度(列/行)(最大化左下角的“NA补丁”)

非常感谢您的帮助!

r matrix sparse-matrix
3个回答
0
投票

或许你可以尝试一下

t(
    replace(
        m,
        t(!is.na(cbind(rbind(replace(
            matrix(1, n - 1, n - 1),
            seq(n^2 - length(v)), NA
        ), 1), 1)[n:1, ])),
        seq_along(v)
    )
)

这给出了

     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]   NA   NA    5    6
[3,]   NA   NA   NA    7
[4,]   NA   NA   NA    8

0
投票

选择一个非递增整数 n 向量 x,使得 1 <= x <= n:1 and sum(x) equals length(v). x[i] represents the number of non-NA elements in row i of the result matrix.

我们通过使用 CVXR 形成凸优化问题来实现这一点,以便任何可行值都可以提供该问题。定义问题时下面的xval是产生的x的最终值。它找到的解决方案是 c(4, 2, 1, 1) 但由于问题没有明确定义 c(3, 2, 2, 1) 将是另一个有效的解决方案,如果需要约束,我们可以添加额外的约束进一步解决方案。

给定 xval 形成一个逻辑矩阵 m,它类似于结果的转置,并使用 TRUE 显示哪些条目是非 NA。由于 R 逐列存储矩阵,因此更容易填充转置。最后填充然后进行转置得到结果M。

v <- letters[1:8]
n <- ceiling((-1 + sqrt(1 + 8 * length(v))) / 2)

library(CVXR)
x <- Variable(n, integer = TRUE)
objective <- Minimize(0)
constraints <- list(sum(x) == length(v), diff(x) <= 0, x >= 1, x <= n:1)
problem <- Problem(objective, constraints)
soln <- solve(problem)
xval <- as.integer(soln$getValue(x) + 0.01)
xval
## [1] 4 2 1 1

m <- matrix(NA, n, n)
m[sapply(c(xval), function(i) rep(c(F, T), c(n-i, i)))] <- seq_along(v)
M <- t(m)

M
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]   NA   NA    5    6
## [3,]   NA   NA   NA    7
## [4,]   NA   NA   NA    8

0
投票

有这样的事吗?

f <- function(v) {
  n <- length(v)
  # number of rows of the square matrix
  m <- ceiling(sqrt(0.25 + 2*n) - 0.5)
  x <- array(NA, rep(m, 2))
  s <- pmin(m + 1L - row(x), col(x)) + pmax(m + 1L - row(x), col(x))/n + (m + 1L)*upper.tri(x)
  x[sort(order(s)[1:n])] <- v
  t(x)
}

测试长度最长为 14 的向量:

lapply(1:14, \(i) f(1:i))
#> [[1]]
#>      [,1]
#> [1,]    1
#> 
#> [[2]]
#>      [,1] [,2]
#> [1,]    1    2
#> [2,]   NA   NA
#> 
#> [[3]]
#>      [,1] [,2]
#> [1,]    1    2
#> [2,]   NA    3
#> 
#> [[4]]
#>      [,1] [,2] [,3]
#> [1,]    1    2    3
#> [2,]   NA   NA    4
#> [3,]   NA   NA   NA
#> 
#> [[5]]
#>      [,1] [,2] [,3]
#> [1,]    1    2    3
#> [2,]   NA   NA    4
#> [3,]   NA   NA    5
#> 
#> [[6]]
#>      [,1] [,2] [,3]
#> [1,]    1    2    3
#> [2,]   NA    4    5
#> [3,]   NA   NA    6
#> 
#> [[7]]
#>      [,1] [,2] [,3] [,4]
#> [1,]    1    2    3    4
#> [2,]   NA   NA   NA    5
#> [3,]   NA   NA   NA    6
#> [4,]   NA   NA   NA    7
#> 
#> [[8]]
#>      [,1] [,2] [,3] [,4]
#> [1,]    1    2    3    4
#> [2,]   NA   NA    5    6
#> [3,]   NA   NA   NA    7
#> [4,]   NA   NA   NA    8
#> 
#> [[9]]
#>      [,1] [,2] [,3] [,4]
#> [1,]    1    2    3    4
#> [2,]   NA    5    6    7
#> [3,]   NA   NA   NA    8
#> [4,]   NA   NA   NA    9
#> 
#> [[10]]
#>      [,1] [,2] [,3] [,4]
#> [1,]    1    2    3    4
#> [2,]   NA    5    6    7
#> [3,]   NA   NA    8    9
#> [4,]   NA   NA   NA   10
#> 
#> [[11]]
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]    1    2    3    4    5
#> [2,]   NA   NA    6    7    8
#> [3,]   NA   NA   NA   NA    9
#> [4,]   NA   NA   NA   NA   10
#> [5,]   NA   NA   NA   NA   11
#> 
#> [[12]]
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]    1    2    3    4    5
#> [2,]   NA   NA    6    7    8
#> [3,]   NA   NA   NA    9   10
#> [4,]   NA   NA   NA   NA   11
#> [5,]   NA   NA   NA   NA   12
#> 
#> [[13]]
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]    1    2    3    4    5
#> [2,]   NA    6    7    8    9
#> [3,]   NA   NA   NA   10   11
#> [4,]   NA   NA   NA   NA   12
#> [5,]   NA   NA   NA   NA   13
#> 
#> [[14]]
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]    1    2    3    4    5
#> [2,]   NA    6    7    8    9
#> [3,]   NA   NA   NA   10   11
#> [4,]   NA   NA   NA   12   13
#> [5,]   NA   NA   NA   NA   14
© www.soinside.com 2019 - 2024. All rights reserved.