将上三角矩阵转换为 R 中的对称矩阵
Posted
技术标签:
【中文标题】将上三角矩阵转换为 R 中的对称矩阵【英文标题】:convert uppertriangular matrix to a symmetric matrix in R 【发布时间】:2017-11-02 18:47:47 【问题描述】:我有一个包含 20 行的数据框,其中每一行是一个 10 x 10 对角线的上三角协方差矩阵,我想将其转换为一个对称的 10X10 矩阵。我一直在关注这个帖子:a vector to an upper Triangle matrix by row in R 但是当我这样做时,它会给我一个列表而不是矩阵。
我还想对每一行进行递归处理,并将生成的 20 个矩阵存储在一个列表中。对于可重现的示例,这里是一个有 20 行的数据框。每行是对角线的 3x3 上三角矩阵。
g <- data.frame(a=runif(20),b=runif(20),c=runif(20),d=runif(20),e=runif(20),f=runif(20))
g1<-c(g[1,])
g2= matrix(0, 3, 3)
g2[upper.tri(g2, diag=TRUE)]=g1
g2
# list of 9 elements instead of matrix
#[[1]]
# [1] 0.2625916
# [[2]]
# [1] 0
# [[3]]
# [1] 0
# [[4]]
# [1] 0.6255627
# [[5]]
# [1] 0.829801
# [[6]]
# [1] 0
# [[7]]
# [1] 0.3386346
# [[8]]
#[1] 0.9517039
# [[9]]
# [1] 0.5886387
【问题讨论】:
不要递归地做,这是一个特定的编程术语,你可能想在一个循环中做它? 【参考方案1】:从给定的数据类型开始:
g<-data.frame(a=runif(20),b=runif(20),c=runif(20),d=runif(20),e=runif(20),f=runif(20))
您需要使用函数unlist(...)
来更改矩阵中的单个单元格:
> g1<-c(g[1,])
> g2<-matrix(0, 3, 3)
> g2[upper.tri(g2, diag=TRUE)] <- unlist(g1)
> g2
[,1] [,2] [,3]
[1,] 0.02287811 0.2938224 0.1224342
[2,] 0.00000000 0.7950484 0.1134449
[3,] 0.00000000 0.0000000 0.7219712
创建上三角矩阵后,您可以通过将数据从上三角矩阵元素复制到下三角矩阵元素来使矩阵对称
> g2[lower.tri(g2,diag=FALSE)] <- g2[upper.tri(g2,diag=FALSE)]
> g2
[,1] [,2] [,3]
[1,] 0.02287811 0.2938224 0.1224342
[2,] 0.29382240 0.7950484 0.1134449
[3,] 0.12243420 0.1134449 0.7219712
然后可以将原始数据集中的所有矩阵组合成一个列表,如下所示:
symlist = list()
for (i in 1:dim(g)[1])
g2 <- matrix(0, 3, 3)
g2[upper.tri(g2,diag=TRUE)] <- unlist(g[i,])
g2[lower.tri(g2,diag=FALSE)] <- g2[upper.tri(g2,diag=FALSE)]
symlist[[i]] <- g2
例如,这里是生成列表中的最后一个矩阵:
> length(symlist)
[1] 20
> symlist[[length(symlist)]]
[,1] [,2] [,3]
[1,] 0.4224727 0.9737866 0.4250256
[2,] 0.9737866 0.7167033 0.2627082
[3,] 0.4250256 0.2627082 0.7556802
【讨论】:
在取消列出矩阵的条目后,是否可以按行而不是按列分配值?【参考方案2】:@Heikki 的答案仅适用于 3x3 矩阵(考虑到列填充)
作为一种解决方法,您可以填充上三角部分,转置临时矩阵(使上三角变为正确的下三角),然后再次填充上三角:
g2[upper.tri(g2, diag=TRUE)] <- unlist(g1)
g2 <- t(g2)
g2[upper.tri(g2, diag=TRUE)] <- unlist(g1)
这也适用于更大的矩阵。示例:
X <- matrix(0, k <- 4, k)
X[upper.tri(X, diag=T)] <- 1:(k*(k+1)/2)
X <- t(X)
X[upper.tri(X, diag=T)] <- 1:(k*(k+1)/2)
[,1] [,2] [,3] [,4]
[1,] 1 2 4 7
[2,] 2 3 5 8
[3,] 4 5 6 9
[4,] 7 8 9 10
【讨论】:
以上是关于将上三角矩阵转换为 R 中的对称矩阵的主要内容,如果未能解决你的问题,请参考以下文章