按行而不是按列用向量填充下矩阵

发布于 2024-10-22 07:46:24 字数 1113 浏览 5 评论 0原文

我正在尝试读取由 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”吗?)

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.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 a lower diagonal matrix (including 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 can read in the values correctly with scan() or read.table(fill=T).

I am however not able to correctly store the read-in vector in a matrix. The following code

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

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

Using matrix() does allow for the option byrow=TRUE, but this will fill in the whole matrix, not just the lower half (with diagonal).

Is it possible to have both: only fill the lower matrix (with diagonal) and do it by row?

(separate issue I'm having: LISREL uses 'D+01' while R only recognises 'E+01' for scientific notation. Can you change this in R to accept also 'D'?)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

微暖i 2024-10-29 07:46:24

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

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

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

S <- diag(6)
S[upper.tri(S, diag=TRUE)] <- d
t(S)
伊面 2024-10-29 07:46:24

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文