Error: The observed correlation matrix is not 1's along the diagonal

Posted on
Picture of user. tbates Joined: 07/31/2009

Getting this error
Error: The observed correlation matrix is not 1's along the diagonal

from the statement
mxData(cor, type="cor", numObs=1656)

but looking at the data matrix indicates that its diagonal consists of 1's

> diag(cor)
SOF IWF PWF FSC FSF EF GPA
1 1 1 1 1 1 1

cor
SOF IWF PWF FSC FSF EF GPA
SOF 1.00000000 -0.310734680 0.02337843 -0.01050081 0.324939442 -0.49945847 0.83664278
IWF -0.31073468 1.000000000 0.09947420 -0.03052640 0.001136279 0.49532944 -0.10899843
PWF 0.02337843 0.099474205 1.00000000 -0.61560751 -0.628812462 0.11562605 -0.21215413
FSC -0.01050081 -0.030526399 -0.61560751 1.00000000 0.048027377 -0.41138615 -0.12042060
FSF 0.32493944 0.001136279 -0.62881246 0.04802738 1.000000000 -0.13170374 0.52886839
EF -0.49945847 0.495329442 0.11562605 -0.41138615 -0.131703740 1.00000000 -0.04665071
GPA 0.83664278 -0.108998427 -0.21215413 -0.12042060 0.528868389 -0.04665071 1.00000000

Full code to make model copied below

#install.packages("ggm")
require(ggm)
cor = rcorr(7)
manifests = c("SOF", "IWF", "PWF", "FSC", "FSF", "EF", "GPA")
dimnames(cor)<-list(manifests,manifests)
fit1<- mxModel("model", type="RAM",
manifestVars = manifests,
mxPath(from = manifests, arrows=2),
mxPath(from = "PWF", to=c("FSF","FSC"), arrows=1),
mxPath(from = "PWF", to="IWF" , arrows=1),
mxPath(from = "PWF", to="SOF" , arrows=1),
mxPath(from = "SOF", to="IWF" , arrows=1),
mxPath(from = "SOF", to=c("FSF","FSC") , arrows=1),

mxPath(from= "IWF", to=c("FSF","FSC") , arrows=1),
mxPath(from= "FSC", to="EF" , arrows=1),
mxPath(from= "FSF", to="EF" , arrows=1),
mxPath(from= "EF" , to="GPA" , arrows=1),
mxData(cor, type="cor", numObs=1656)
)

Replied on Thu, 11/10/2011 - 09:04
Picture of user. mspiegel Joined: Jul 31, 2009

Interesting. It appears that the diagonal of the correlation matrix has entries that are very slightly not equal to one:

> diag(cor) - 1.0
[1] -1.110223e-16 -1.110223e-16  0.000000e+00 -2.220446e-16 -1.110223e-16
[6]  0.000000e+00  0.000000e+00

An easy way to run the model is just to set diag(cor) <- 1. An easy improvement of the current situation would be to augment the error message to say, "The observed correlation matrix is almost equal to, but not identical, to 1's along the diagonal." The larger question is whether or not to allow these input matrices? My inclination is not to allow them, since the eplison that we would need to choose for approximate equality is an arbitrary value.

Replied on Thu, 11/10/2011 - 12:01
Picture of user. tbates Joined: Jul 31, 2009

In reply to by mspiegel

nice one michael!

I found that taking cov2cor() made the error go away, but the fact that diag() printed 1 with no decimals threw me off the scent...

Reporting the error as you suggest would be fantastic, perhaps noting that cov2cor() can fix this if it is an error...

t

Replied on Thu, 11/10/2011 - 12:32
No user picture. JWiley Joined: Mar 25, 2011

In reply to by tbates

yep, because the penultimate line of cov2cor is:

r[cbind(1L:p, 1L:p)] <- 1

which uses the matrix indexes for diagonals and sets them to 1 :)

cleaner 'fix' then cov2cor would just be: diag(cor) <- 1