--- title: "Finding the nearest proper correlation matrix" author: "Kevin Wright" date: "`r Sys.Date()`" bibliography: corrgram.bib output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Finding the nearest proper correlation matrix} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- Consider the following matrix, as might arise from calculating covariance based on pairwise-complete data. ```{r} vv <- matrix(c(100.511, 159.266, 3.888, 59.964, 37.231, 32.944, 68.845, 159.266, 277.723, 6.161, 95.017, 58.995, 52.203, 109.09, 3.888, 6.161, 99.831, 2.32, 1.44, 1.274, 2.663, 59.964, 95.017, 2.32, 35.774, 22.212, 19.655, 41.073, 37.231, 58.995, 1.44, 22.212, 40.432, 12.203, 25.502, 32.944, 52.203, 1.274, 19.655, 12.203, 10.798, 22.566, 68.845, 109.09, 2.663, 41.073, 25.502, 22.566, 96.217), nrow=7, byrow=TRUE) print(vv) ``` This is not a proper covariance matrix (it has a negative eigenvalue). ```{r} eigen(vv)$values ``` If we attempt to use the `cov2cor()` function to convert the covariance matrix to a correlation matrix, we find the largest correlation values are slightly larger than 1.0. ```{r} cc <- cov2cor(vv) max(cc) # 1.000041 ``` If this is passed to the `corrgram` function, it will issue a warning that the input data is not a correlation matrix and then calculate pairwise correlations of the columns, resulting in a non-sensical graph. There are several packages with functions that can be used to force the correlation matrix to be an actual, positive-definite correlation matrix. Two are given here. ## psych ```{r} require(psych) cc2 <- psych::cor.smooth(cc) max(cc2) ``` ## sfsmisc ```{r} library(sfsmisc) # nearcor uses 'identical' and says the matrix is not symmetric isSymmetric(cc) # TRUE identical(cc, t(cc)) # FALSE # round slightly to make it symmetric cc3 <- nearcor(round(cc,12))$cor max(cc3) ``` After converting the matrix to a valid correlation matrix, an accurate corrgram can be created: ```{r, fig.width=6, fig.height=6, fig.align="center"} require(corrgram) corrgram(cc2, lower=panel.cor) ```