Skip to content

Difference between two correlation matrices

6 messages · michael watson (IAH-C), Marta Rufino, Stéphane Dray +2 more

#
Hi 

Now a more theoretical question.  I have two correlation matrices - one
of a set of variables under a particular condition, the other of the
same set of variables under a different condition.  Is there a
statistical test I can use to see if these correlation matrices are
"different"?

Thanks
Mick
#
Hello,

I don't know if it is applicable in your case, but have you tried Mantel
test?
You can use it to determine significant correlation between two matrices,
using Pearsion, Spearman or Kendal correlation indices.

Hope it helps,
All the best,
Marta


----- Original Message ----- 
From: "michael watson (IAH-C)" <michael.watson at bbsrc.ac.uk>
To: <r-help at stat.math.ethz.ch>
Sent: Tuesday, November 16, 2004 2:49 PM
Subject: [R] Difference between two correlation matrices
http://www.R-project.org/posting-guide.html
#
One solution is to use procruste analysis.
Perform a principal coordinate analysis on your data (cmdscale) to obtain 
two individuals by variables tables.
Then, you can perform procruste rotation and test to know if the two 
matrice tell the same thing. It is more powerful than mantel test.
As you have correlations, I suppose than you can consider your original 
variables rather than correlation and cmdscale



Functions are available in the ade4 package:

procuste(ade4)          Simple Procruste Rotation between two sets of
                         points
procuste.randtest(ade4)
                         Monte-Carlo Test on the sum of the singular
                         values of a procustean rotation (in C).
procuste.rtest(ade4)    Monte-Carlo Test on the sum of the singular
                         values of a procustean rotation (in R).

A reference on the analysis:

<http://www.steph280.freesurf.fr/files/articles/Ecosci2003.pdf>S. Dray, D. 
Chessel, J. Thioulouse : Procrustean co-inertia analysis for the linking of 
ecological tables. 
Ecoscience<http://www.steph280.freesurf.fr/files/articles/Ecosci2003.pdf>, 
2003, vol. 10, 110-119.

available at :

http://www.steph280.freesurf.fr/files/articles/Ecosci2003.pdf

Hope this helps !
At 10:31 16/11/2004, Marta Rufino wrote:
St??phane DRAY
-------------------------------------------------------------------------------------------------- 

D??partement des Sciences Biologiques
Universit?? de Montr??al, C.P. 6128, succursale centre-ville
Montr??al, Qu??bec H3C 3J7, Canada

Tel : (514) 343-6111 poste 1233         Fax : (514) 343-2293
E-mail : stephane.dray at umontreal.ca
-------------------------------------------------------------------------------------------------- 

Web                                          http://www.steph280.freesurf.fr/
#
If you have the data that created the correlation matrices, then
you can do a permutation test.

The first question to ask is, "What does 'different' mean?"
Some choices include:

max(abs(cor1 - cor2))

max(abs(eigen(cor1 - cor2)$values))

Once you have decided what metric makes most sense, you can
perform the test. First pool all of the data (if you think that there
are different means in the two conditions, then remove the means
within each group before pooling).  Then perform a number of
random allocations of the pooled data  into two groups with the
number in each group equal to the original numbers.  The test
compares your statistic using the original correlation matrices to
the distribution of statistics of the correlations from the random
allocations.

Patrick Burns

Burns Statistics
patrick at burns-stat.com
+44 (0)20 8525 0696
http://www.burns-stat.com
(home of S Poetry and "A Guide for the Unwilling S User")
michael watson (IAH-C) wrote:

            
3 days later
#
michael watson (IAH-C) writes:
If you can assume multivariate normality, you can use a test of
hypothesis to test if the covariance+ matrices are equal. Such a test is
described for example in Anderson (1958)*.

        I am currently working on implementing some multivariate tests
on R (sphericity test, equality of covariance matrices, etc). Attached
follows a preliminary version of varcomp(): this function implements the
test for equality of covariance matrices under multivare normality
aforementioned. It takes as first argument a list with the covariance
matrices and a vector n indicating the sample size used to calculate
each of them.

        Example of use: Suppose you have 3 estimated covariance matrices
S1, S2, S3, from a sample of 3 bivariate normal populations with unkown
covariance matrices. The sample size for each Si, was 11,12,11.

        S1 <- matrix(c(7.17,19.47,19.47,113.38),byrow=T,ncol=2)
        S2 <- matrix(c(20.33,59.78,59.78,229.02),byrow=T,ncol=2)
        S3 <- matrix(c(5.22,17.33,17.33,112.88),byrow=T,ncol=2)
        varcomp(list(S1,S2,S3),n=c(11,12,11))

        
  Will test H0: Sigma1 = Sigma2 = Sigma3, vs. H1: at least two of
them are different from each other. 

        Beware though that it's still work in progress, I've tested it
for a few examples and it gave sensible results, but it still needs some
polishing.

* An Introduction to Multivariate Analysis, Wiley.
+ note that a correlation matrix is a special type of a covariance
matrix, so you can use a test of hypothesis designed for covariance
matrices. 


--
Fernando Henrique Ferraz P. da Rosa
http://www.ime.usp.br/~feferraz
#
er.. forgot to attach the file. there it goes. (sorry)

michael watson (IAH-C) writes:
--
Fernando Henrique Ferraz P. da Rosa
http://www.ime.usp.br/~feferraz
-------------- next part --------------
varcomp <- function(covmat,n) {
   if (is.list(covmat)) {
	if (length(covmat) < 2) 
	    stop("covmat must be a list with at least 2 elements")
	ps <- as.vector(sapply(covmat,dim))
	if (sum(ps[1] == ps) != length(ps))
	    stop("all covariance matrices must have the same dimension")
	p <- ps[1]	
        q <- length(covmat)
        if (length(n) == 1)
	    Ng <- rep(n,q)
	else if (length(n) == q) 
	    Ng <- n
	else 
	    stop("n must be equal length(covmat) or 1")
            
	DNAME <- deparse(substitute(covmat))
   }

   else
	stop("covmat must be a list")

   ng <- Ng - 1
   Ag <- lapply(1:length(covmat),function(i,mat,n) { n[i] * mat[[i]] },mat=covmat,n=ng)
   A <- matrix(colSums(matrix(unlist(Ag),ncol=p^2,byrow=T)),ncol=p)
   detAg <- sapply(Ag,det)
   detA <- det(A)
   V1 <- prod(detAg^(ng/2))/(detA^(sum(ng)/2))
   kg <- ng/sum(ng)
   l1 <- prod((1/kg)^kg)^(p*sum(ng)/2) * V1
   rho <- 1 - (sum(1/ng) - 1/sum(ng))*(2*p^2+3*p-1)/(6*(p+1)*(q-1))
   w2 <- p*(p+1) * ((p-1)*(p+2) * (sum(1/ng^2) - 1/(sum(ng)^2)) - 6*(q-1)*(1-rho)^2) / (48*rho^2)
   f <- 0.5 * (q-1)*p*(p+1)
   STATISTIC <- -2*rho*log(l1)
   PVAL <- 1 - (pchisq(STATISTIC,f) + w2*(pchisq(STATISTIC,f+4) - pchisq(STATISTIC,f)))
   names(STATISTIC) <- "corrected lambda*"
   names(f) <- "df"
   RVAL <- structure(list(statistic = STATISTIC, parameter = f,p.value = PVAL, data.name = DNAME, method = "Equality of Covariances Matrices Test"),class="htest")
   return(RVAL)
}