我正在寻找一种方法,通过语言 R 中的成对索引来索引对称矩阵的下三角矢量。这是一些解释性代码:
M
是n
次n
成对矩阵,此处包含随机数据(仅显示):
n <- 5
set.seed(0815)
M <- matrix(sample(n^2),n,n)
M[upper.tri(M)] <- t(M)[upper.tri(M)]
diag(M) <- 0
M
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0 6 3 18 10
# [2,] 6 0 11 23 9
# [3,] 3 11 0 5 21
# [4,] 18 23 5 0 16
# [5,] 10 9 21 16 0
我的数据(x
)是矩阵M
中的下三角矢量:
x <- M[lower.tri(M)]
我要提取的索引对存储在名为i
:
i <- c(2:3,5)
我的目标是从下三角矢量中提取对,如下面的矩阵示例所示。
aim <- M[i,i][lower.tri(M[i,i])]
aim
# [1] 11 9 21
因为在我的情况下M
不可用且我不想从x
生成它(内存问题),所以我创建了以下索引函数f
:
f <- function (n,i) {
r <- combn(i,2)[1,]
c <- combn(i,2)[2,]
n * r + c - (r * (r + 1))/2 - n
}
res <- x[f(n,i)]
identical(res, aim)
# [1] TRUE
在函数f
的R中是否有更优雅或已经内置版本,也许还需要n
参数,从x
的长度计算它?
提前谢谢。
斯文
答案 0 :(得分:2)
我认为您最好的方法是使用Matrix
库中的某些内容来存储原始矩阵。它有几个很好的功能,我希望能够更容易地处理这样的矩阵。
这里我使用dtpMatrix
(密集,三角形,包装,矩阵),没有对角线。这在内存中占用的空间与x
相同,加上跟踪矩阵大小等等。通过使用它,您可以通常的方式引用行和列。然后,我可以从i
中获取所需的行和列,但请注意,-1
是必需的,因为我没有存储对角线。另请注意,@x
只返回矩阵的下三角部分,因为它是如何在内部存储的。
library(Matrix)
k <- length(x)
n <- as.integer(((sqrt(8 * k + 1) + 1) / 2) - 1)
M2 <- new("dtpMatrix", uplo="L", diag="N", Dim=c(n, n), x=x)
M2[i[-1] - 1, i[-length(i)]]@x
## [1] 11 9 21
顺便说一句,请注意,如上所述,这也会从n
的长度计算x
。
答案 1 :(得分:0)
再看一遍之后,我很困惑你不只是这样做了:
x[i]
#[1] 3 18 11
如果您不希望将中间值分配给x
,则可以使用:
M[lower.tri(M)][i]
#[1] 3 18 11