【问题标题】:Fill lower matrix with vector by row, not column用行填充下矩阵,而不是列
【发布时间】:2011-03-15 23:48:38
【问题描述】:

我正在尝试读取由 LISREL 以以下格式在纯文本、空格分隔的文件中写入的方差-协方差矩阵:

 0.23675E+01  0.86752E+00  0.28675E+01 -0.36190E+00 -0.36190E+00  0.25381E+01
-0.32571E+00 -0.32571E+00  0.84425E+00  0.25598E+01 -0.37680E+00 -0.37680E+00
 0.53136E+00  0.47822E+00  0.21120E+01 -0.37680E+00 -0.37680E+00  0.53136E+00
 0.47822E+00  0.91200E+00  0.21120E+01

这其实是一个下对角矩阵(包括对角线):

 0.23675E+01  
 0.86752E+00  0.28675E+01 
-0.36190E+00 -0.36190E+00  0.25381E+01
-0.32571E+00 -0.32571E+00  0.84425E+00  0.25598E+01 
-0.37680E+00 -0.37680E+00  0.53136E+00  0.47822E+00  0.21120E+01 
-0.37680E+00 -0.37680E+00  0.53136E+00  0.47822E+00  0.91200E+00  0.21120E+01

我可以使用scan()read.table(fill=T) 正确读取值。

但是,我无法将读入的向量正确存储在矩阵中。以下代码

S <- diag(6)
S[lower.tri(S,diag=T)] <- d

按列填充下部矩阵,而应按行填充。

使用matrix() 确实允许选项byrow=TRUE,但这将填充整个矩阵,而不仅仅是下半部分(对角线)。

是否可以两者兼得:只填充下部矩阵(对角线)逐行填充?

(我遇到的另一个问题:LISREL 使用 'D+01' 而 R 只识别 'E+01' 作为科学记数法。你可以在 R 中更改它以接受 'D' 吗?)

【问题讨论】:

    标签: r matrix covariance


    【解决方案1】:

    只需将其读入上三角部分,而不是下三角部分:

    S <- diag(6)
    S[upper.tri(S, diag=TRUE)] <- d
    t(S)
    

    【讨论】:

      【解决方案2】:

      sem 包有一个很好的功能,read.moments() 就是专门为此设计的:

      foo <- read.moments()
       0.23675E+01  
       0.86752E+00  0.28675E+01 
      -0.36190E+00 -0.36190E+00  0.25381E+01
      -0.32571E+00 -0.32571E+00  0.84425E+00  0.25598E+01 
      -0.37680E+00 -0.37680E+00  0.53136E+00  0.47822E+00  0.21120E+01 
      -0.37680E+00 -0.37680E+00  0.53136E+00  0.47822E+00  0.91200E+00  0.21120E+01
      
      foo[upper.tri(foo)] <- t(foo)[upper.tri(foo)]
      

      这给了你:

               X1       X2       X3       X4       X5       X6
      X1  2.36750  0.86752 -0.36190 -0.32571 -0.37680 -0.37680
      X2  0.86752  2.86750 -0.36190 -0.32571 -0.37680 -0.37680
      X3 -0.36190 -0.36190  2.53810  0.84425  0.53136  0.53136
      X4 -0.32571 -0.32571  0.84425  2.55980  0.47822  0.47822
      X5 -0.37680 -0.37680  0.53136  0.47822  2.11200  0.91200
      X6 -0.37680 -0.37680  0.53136  0.47822  0.91200  2.11200
      

      EDIT1:至于scan()的问题,仅仅因为它最初被打印为下三角形并不意味着你必须将它放在下三角形中:)将它放在上面:

      foo <- scan()
       0.23675E+01  
       0.86752E+00  0.28675E+01 
      -0.36190E+00 -0.36190E+00  0.25381E+01
      -0.32571E+00 -0.32571E+00  0.84425E+00  0.25598E+01 
      -0.37680E+00 -0.37680E+00  0.53136E+00  0.47822E+00  0.21120E+01 
      -0.37680E+00 -0.37680E+00  0.53136E+00  0.47822E+00  0.91200E+00  0.21120E+01
      
      bar <- matrix(0,6,6)
      
      bar[upper.tri(bar,diag=TRUE)] <- foo
      
      bar[lower.tri(bar)] <- t(bar)[lower.tri(bar)]
      

      EDIT2:至于D符号的问题,如果我理解正确,可以通过先扫描字符来解决,gsub D 到 E 并强制为数字:

      foo <- scan(what="character")
       0.23675D+01  
       0.86752D+00  0.28675D+01 
      -0.36190D+00 -0.36190D+00  0.25381D+01
      -0.32571D+00 -0.32571D+00  0.84425D+00  0.25598D+01 
      -0.37680D+00 -0.37680D+00  0.53136D+00  0.47822D+00  0.21120D+01 
      -0.37680D+00 -0.37680D+00  0.53136D+00  0.47822D+00  0.91200D+00  0.21120D+01
      
      
      bar <- matrix(0,6,6)
      
      bar[upper.tri(bar,diag=TRUE)] <- as.numeric(gsub("D","E",foo))
      
      bar[lower.tri(bar)] <- t(bar)[lower.tri(bar)]
      
      bar
      

      【讨论】:

        猜你喜欢
        • 2020-04-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-22
        • 2016-10-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多