Fill lower matrix with vector by row, not column

后端 未结 2 488
孤城傲影
孤城傲影 2021-01-19 01:21

I am trying to read in a variance-covariance matrix written out by LISREL in the following format in a plain text, whitespace separated file:

 0.23675E+01  0         


        
相关标签:
2条回答
  • 2021-01-19 02:10

    The sem package has a very nice function, read.moments() that is designed to do just this:

    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)]
    

    This gives you:

             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: As for the problem with scan(), just because it was originally printed as a lower triangle doesn't mean you have to put it in the lower triangle:) Just put it in the upper:

    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: As for the problem with D notation, if I understand it correctly, can be fixed by first scanning characters, gsub the D to E and coerce as numeric:

    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
    
    0 讨论(0)
  • 2021-01-19 02:18

    Just read it into the upper triangular portion, rather than the lower:

    S <- diag(6)
    S[upper.tri(S, diag=TRUE)] <- d
    t(S)
    
    0 讨论(0)
提交回复
热议问题