Fill the bottom matrix with a row vector rather than a column

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

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 

This is actually the bottom diagonal matrix (including the diagonal):

  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 

I am reading values ​​correctly with scan() or read.table(fill=T) .

However, I cannot save the read vector in the matrix correctly. Following code

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

fills the bottom matrix by column, while it should fill it by row.

Using matrix() allows you to use the byrow=TRUE parameter, but this will fill the entire matrix, not just the bottom half (with a diagonal).

Is it possible to have both: fill in the bottom matrix (with a diagonal) and do it line by line?

(separate release that I have: LISREL uses β€œD + 01”, while R only recognizes β€œE + 01” for scientific notation. Can you change this to R to accept also β€œD”?)

+4
matrix covariance r
source share
2 answers

Just read it in the upper triangular part and not in the lower part:

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

The sem package has a very nice read.moments() function designed for 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: Regarding the problem with scan() , just because it was originally printed as a lower triangle does not mean you have to put it in the lower triangle :) Just put it on the top:

 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: Regarding the problem with the notation D , if I understand it correctly, you can fix it with the first scanning characters, gsub from D to E and force 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 
+1
source share