2011-03-15 14 views
6

Estoy tratando de leer en una matriz de varianza-covarianza escrita por LISREL en el siguiente formato en un texto plano, espacio en blanco separado:Llenar la matriz inferior con el vector por fila, no la columna

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 

Este es en realidad una matriz diagonal inferior (incluyendo 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 

puedo leer en los valores correctamente con scan() o read.table(fill=T).

estoy sin embargo no es capaz de almacenar correctamente la lectura en el vector en una matriz. El siguiente código

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

llena la matriz inferior por columna, mientras que debería llenarse por fila.

El uso de matrix() permite la opción byrow=TRUE, pero esto llenará toda la matriz, no solo la mitad inferior (con diagonal).

¿Es posible tener ambos: solo llene la matriz inferior (con diagonal) y hacerlo por fila?

(tema aparte que estoy teniendo:. LISREL 'D + 01' usos mientras que R sólo reconoce 'E + 01' para la notación científica ¿Se puede cambiar esto en R aceptar también 'D'?)

Respuesta

10

Sólo leerlo en la porción triangular superior, en lugar de la inferior:

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

el paquete sem tiene una función muy agradable, read.moments() que está diseñado para hacer precisamente esto:

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

esto le da:

  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: En cuanto al problema scan(), sólo porque ella fue impresa originalmente como un triángulo inferior no significa que tenga que ponerlo en el triángulo inferior :) Basta con colocarlo en la parte superior:

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: en cuanto al problema D notación, si he entendido bien, puede ser fijado por primeros caracteres de exploración, gsub la D a e y coaccionar como numérico:

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 
Cuestiones relacionadas