I created a symmetric matrix that is required for input to the sem() function in R, but keep getting an error that says the matrix is not symmetric.
When I check element-by-element, I find no differences.
Does isSymmetric() check with a higher precision? If so, how can I coerce the matrix to be symmetric in memory?
SCA = c(1,.73,.70,.58,.46,.56)
PPE = c(.73,1,.68,.61,.43,.52)
PTE = c(.7,.68,1,.57,.4,.48)
PFE = c(.58,.61,.57,1,.37,.41)
EA = c(.46,.43,.4,.37,1,.72)
CP = c(.56,.52,.48,.41,.71,1)
ability = as.matrix(cbind(SCA,PPE,PTE,PFE,EA,CP))
rownames(ability)=t(colnames(ability))
ability.diag = diag(ability)
ability[lower.tri(ability,diag=T)] = 0
ability = ability + t(ability) + diag(ability.diag)
ability
# SCA PPE PTE PFE EA CP
# SCA 1.00 0.73 0.70 0.58 0.46 0.56
# PPE 0.73 1.00 0.68 0.61 0.43 0.52
# PTE 0.70 0.68 1.00 0.57 0.40 0.48
# PFE 0.58 0.61 0.57 1.00 0.37 0.41
# EA 0.46 0.43 0.40 0.37 1.00 0.71
# CP 0.56 0.52 0.48 0.41 0.71 1.00
sum(ability != t(ability))
# [1] 0
isSymmetric(ability)
# [1] FALSE
The function isSymmetric is implemented using the function all.equal. What is being tested is not whether the matrix is equal to its transpose, element by element, but whether these two matrices are equal as R objects. And in your case, they're not: if you look at their structure, you get the following:
> str(ability)
num [1:6, 1:6] 1 0.73 0.7 0.58 0.46 0.56 0.73 1 0.68 0.61 ...
- attr(*, "dimnames")=List of 2
..$ : chr [1, 1:6] "SCA" "PPE" "PTE" "PFE" ...
..$ : chr [1:6] "SCA" "PPE" "PTE" "PFE" ...
> str(t(ability))
num [1:6, 1:6] 1 0.73 0.7 0.58 0.46 0.56 0.73 1 0.68 0.61 ...
- attr(*, "dimnames")=List of 2
..$ : chr [1:6] "SCA" "PPE" "PTE" "PFE" ...
..$ : chr [1, 1:6] "SCA" "PPE" "PTE" "PFE" ...
So the problem is with how the row names of ability have been generated. You can easily fix this:
> rownames(ability) <- colnames(ability)
> isSymmetric(ability)
[1] TRUE
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With