2

我正在寻找一种方法,通过语言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

先感谢您。

斯文

4

2 回答 2

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,如前所述。

于 2014-08-09T02:51:25.030 回答
0

再次查看此内容后,我很困惑您不只是这样做:

x[i]
#[1]  3 18 11

如果您不希望分配给x您的中间值可以使用:

M[lower.tri(M)][i]
#[1]  3 18 11
于 2014-08-09T01:09:40.770 回答