将半向量化转换为全矩阵的最聪明方法

时间:2018-07-19 10:36:59

标签: r matrix linear-algebra

我对上述问题有疑问。我有一个大数据集。每行对应一天,矩阵以向量形式记录,即通过矢量化矩阵的唯一上三角并将其转置为行向量。

我想将整个数据集转换回每天的完整矩阵(观察)。一个简短的可复制示例如下:

structure(list(X01 = c(5.89378246085557, 5.75461814891448, 8.01511372310818
), X02 = c(2.04749233527123, 1.79201580489132, 4.13243690125304
), X03 = c(6.84437620663595, 7.76572007184568, 9.21387189085179
), X04 = c(1.48894672990183, 1.412996838366, 2.60650888282447
), X05 = c(0.951513482112949, 1.37836898031636, 2.74942660284063
), X06 = c(2.68732004256996, 2.70518391829012, 4.74436162847904
), X07 = c(2.15270455626705, 2.47115157067303, 3.92259973345368
), X08 = c(2.12319802206402, 3.08674733009856, 3.91968874234002
), X09 = c(1.92541015217767, 2.62688861593519, 2.84482322630633
), X10 = c(10.2251876218029, 9.5296229460776, 8.46917045978735
), X11 = c(1.23017267644711, 1.1675692778204, 1.93502656632884
), X12 = c(1.24956978625185, 1.78431799528065, 2.81675019026563
), X13 = c(1.07497786235713, 0.422607699395901, 1.51342480871545
), X14 = c(1.36996532434845, 1.85499779637815, 1.49126581139642
), X15 = c(6.33847251476969, 4.54434019245843, 7.27901008329251
), X16 = c(2.08364028735932, 1.74263661965122, 2.25975717022752
), X17 = c(1.24649025820314, 1.95698292727337, 3.12139710484827
), X18 = c(0.647824716200822, 0.805958808007548, 2.33918923838555
), X19 = c(2.05060707165895, 2.06986549088027, 1.99435629106657
), X20 = c(0.655024785094781, 1.22421902352593, 0.811896637188255
), X21 = c(4.20465438339735, 3.4827652599631, 7.63429180588341
)), row.names = c(NA, 3L), class = "data.frame")

该示例包含第一行,因此应将三个矩阵作为预期输出

1 个答案:

答案 0 :(得分:2)

我会创建稀疏矩阵,但是使用as.matrix可以轻松将它们强制转换为密集矩阵。当然,直接创建密集矩阵将是相当琐碎的。

library(Matrix)

fun <- function(x) {
  n <- 0.5 + sqrt(0.25 + 2 * length(x)) #calculate dimension
  i <- sequence(seq_len(n - 1)) #row indices
  j <- rep(seq_len(n - 1), seq_len(n - 1)) + 1 # column indices
  sparseMatrix(i = i, j = j, x = x, triangular = TRUE, dims = c(n, n))
}

matlist <- apply(DF, 1, fun)

#check result
m <- as.matrix(matlist[[1]])
#     [,1]     [,2]     [,3]      [,4]      [,5]     [,6]      [,7]
#[1,]    0 5.893782 2.047492 1.4889467  2.152705 1.230173 2.0836403
#[2,]    0 0.000000 6.844376 0.9515135  2.123198 1.249570 1.2464903
#[3,]    0 0.000000 0.000000 2.6873200  1.925410 1.074978 0.6478247
#[4,]    0 0.000000 0.000000 0.0000000 10.225188 1.369965 2.0506071
#[5,]    0 0.000000 0.000000 0.0000000  0.000000 6.338473 0.6550248
#[6,]    0 0.000000 0.000000 0.0000000  0.000000 0.000000 4.2046544
#[7,]    0 0.000000 0.000000 0.0000000  0.000000 0.000000 0.0000000
all(m[upper.tri(m)] == unlist(DF[1,]))
#[1] TRUE