我正在寻找一种方法,通过语言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
最后,我的问题:
R 中是否有函数 f
的更优雅或已经内置版本,也许也不需要 n
作为参数,根据 x
的长度计算?
提前谢谢您。
斯文
最佳答案
我觉得你最好的办法是使用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
顺便说一句,请注意,如上所述,这还会根据 x
的长度计算 n
。
关于R/Index 下三角向量(按成对索引),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25207595/