# Correlation between matrices in R

I have problems in using the cor() and cor.test() functions.

I just have two matrices (only numerical values, and the same number of row and columns) and I want to have the correlation number and the corresponding p-value.

When I use cor(matrix1, matrix2) I get the correlation coefficients for all the cells. I just want a single number as result of cor.

In additon when I do cor.test(matrix1, matrix2) I get the following error

Error in cor.test.default(matrix1, matrix2) : 'x' must be a numeric vector


How can I get p-values for matrices?

You find the simple tables I want to correlate here:

http://dl.dropbox.com/u/3288659/table_exp1_offline_MEANS.csv

http://dl.dropbox.com/u/3288659/table_exp2_offline_MEANS.csv

• It's a little unclear what you want. When you say you just want one result for cor(matrix1, matrix2), are you trying to correlate (all the numbers in matrix1) with (all the numbers in matrix2)? In that case, you could try cor(as.vector(matrix1), as.vector(matrix2)) Mar 21, 2012 at 1:44
• What is the p-value expected to show, precisely? (i.e., what hypothesis are you testing?)
– chl
Mar 21, 2012 at 7:21
• No, I just want to correlate the two matrices in order to know how much similar they are. I don't want a comparison cell by cell. I just want as a result a single number from 0 to 1, like every pearson correlation does using two vectors in input. Any suggestion? The p-value I expect has to tell me the significance of the correlation.
– L_T
Mar 21, 2012 at 10:12
• Do you mean as in cor(as.vector(matrix1), as.vector(matrix2))?
– whuber
Apr 30, 2012 at 20:42

If you simply want to calculate the correlation between the two sets of values, ignoring the matrix structure, you can convert the matrices to vectors using c(). Then your correlation is computed by cor(c(matrix1), c(matrix2)).

• Using your function I get this error: "Error in cor(c(matrix1), c(matrix2)) : 'x' must be numeric". But if you have a quick look at my tables you notice that they contains only numbers...I do not understand
– L_T
Mar 21, 2012 at 10:14
• An R issue this one: read.csv, which you probably used, returns a data.frame which is a not a matrix. So you need to convert it to being a matrix with as.matrix before making it one long vector with c() and giving the results to cor. Here it is in one line: cor(c(as.matrix(matrix1)), c(as.matrix(matrix2))) Mar 21, 2012 at 12:44

Suppose that your matrices have columns representing two sets of (different) variables and (the same number of) rows representing cases.

Canonical Correlation Analysis

In this situation, one potentially interesting more structured correlation analysis is to find the canonical correlations. This assumes that you want to summarize the relationship between the two sets of variables in terms of the correlation(s) between linear combinations of matrix1 columns and linear combinations of matrix2 columns. And you would want to do that if you suspected that there was a space of small dimensionality, perhaps even 1, that would reveal an underlying correlation structure across the cases that is obscured by their realization in the current variable-defined coordinate systems. Consequently the value of this (canonical) correlation would, in a sense, summarize a multivariate linear relationship between the two matrices. Indeed, while CCA works for matrices with different numbers of variables it reduces to Pearson correlation when each 'matrix' is just a single column.

Implementation

Canonical correlation analysis is described in most multivariate analysis texts, which is perhaps most helpful if you happy with matrix algebra up to eigenanalysis. It is implemented as cancor in base R and also in the CCA package which is described here.

• Hi thanks. My data are simple two matrices containing the same variables. The structure of the two matrices is identical. The values in each cell are the results of an experiment where those variables were evaluated on a 9-points Likert scale and averaged across participants. Which is the best strategy to find in there is correlation between the two matrices? Can you make an example in R?
– L_T
Mar 21, 2012 at 11:02
• With base R it's just cancor(matrix1, matrix2). Mar 21, 2012 at 12:19
• But perhaps you can clarify a bit. Call matrix1 $A$. Then what is $A_{ij}$? Is it the $i$-th person's reponse to the $j$-th Likert item? Surely not. So where does the average over participants come in? Mar 21, 2012 at 12:23
• Hi there were 10 participants, they had to express the "degree of coherence" between pairs stimuli (note it is not a dissimilarity rating experiment). I did 2 experiments. and I want to compare the results under the 2 expdrimental conditions. Each cell is the average of the evaluations of the 1o participants for each pair of stimuli. Then should I still use cancor?
– L_T
Mar 21, 2012 at 13:25
• I used cancor, but I do not get a single coefficient value expressing the correlation nor a p-value expressing its significance. Please help!
– L_T
Mar 21, 2012 at 13:45

If you loosely construe correlation to mean similarity, you can use a definition based on the inner product, such as:

$c_{AB} = \dfrac{\langle A, B \rangle}{\|A \| ||B\|}$ where $\langle A,B \rangle \equiv \mathrm {tr}(A B^T)$ and $\| x || \equiv \langle x,x \rangle^{1/2}$

With your data this yields 0.996672.

The alternative, if the matrix structure is not important, is to simply flatten the matrices into vectors and use the correlation measure of your choice. Since I don't know your data's distribution I used the dot product, to get 0.976.

Eithe3r way, it seems your data is highly correlated.

• This seems the rv coefficient, which is what the OP asked: a value between 0 and 1 that tells how similar both matrices are.
– llrs
Jul 5, 2018 at 14:31

You may want to look into fast distance covariance and correlation which I think R probably has an implementation of.

The answers above have details for R programming to get the Pearson correlation coefficient which is what you asked for. To explore distance correlation here is a quick summary of some steps you could take. The code is in java, but you could port it to R.

To only calculate the correlation between the the same column in each of the 2 datasets of the same size and number of variables, matrix1 and matrix2, you are calculating only the diagonal of a full correlation matrix. And you are wanting to combine those correlations into one number to use as a replacement for similarity between the 2 matrices.

let x1 = matrix1 and x2 = matrix2 below

input: double[][] x1 and double[][] x2 being same size
double[][] dCor = zeros(x1[0].length, x2[0].length);
double[] tmp1 = new double[x2.length];
double[] tmp2 = new double[x2.length];
int i, j, k;
for (i = 0; i < x1[0].length; ++i) {
//for (j = 0; j < x2[0].length; ++j) {
j = i
// copy each column vector to calculate correlation
for (k = 0; k < x2.length; ++k) {
tmp1[k] = x2[k][j];
tmp2[k] = x1[k][i];
}
// fast dcor runtime is O(n*log_2(n))
dCor[i][j] = sqrt(fastDCor(tmp1, tmp2).corSq);
//}
}


where fastDCor is fast distance correlation. reference:

"A fast algorithm for computing distance correlation"
2019 Chaudhuri and Hu, Computational Statistics And Data Analysis,
Volume 135, July 2019, Pages 15-24.


For combining correlation0 with correlation 1 and correlation2 etc. you could browse the short paper:

Charter and Alexander 1993, "A Note on Combining Correlations".


The paper details are for the Pearson correlation, but are informative.