aliocee
aliocee

Reputation: 730

How to calculate correlation between matrices with different column dimention in R

I have two matrices with same number of rows and different number of columns as:

mat1 <- matrix(rnorm(20), 4, 5)
mat2 <- matrix(rnorm(12), 4, 3)

Since i have the same number of rows I want to calculate the following correlation between the columns of the matrices:

 cor.test(mat1[,1], mat2[,1])
 cor.test(mat1[,1], mat2[,2])
 cor.test(mat1[,1], mat2[,3])
 cor.test(mat1[,2], mat2[,1])
 cor.test(mat1[,2], mat2[,2])
 cor.test(mat1[,2], mat2[,3])
 ...........
 ...........
 cor.test(mat1[,5], mat2[,3])

for(i in 1:5){
  for(j in 1:3){
    pv[i,j] <- cor.test(mat1[, i], mat2[ , j])$p.value
  }
}

At the end I want a matrix(5 * 3) or vector containing the correlation values, can anyone help?

Can i use this to return both p.value and estimate?

 FUN <- function(x, y) { 
    res <- cor.test(x, y, method="spearman", exact=F) 
    return(list(c = res$estimate, p = res$p.value)) 
  }

 r1 <- outer(colnames(mat1), colnames(mat2), Vectorize(function(i,j) FUN(mat1[,i], mat2[,j])$p))
 r2 <- outer(colnames(mat1), colnames(mat2), Vectorize(function(i,j) FUN(mat1[,i], mat2[,j])$c))

Thank you.

Upvotes: 2

Views: 3526

Answers (5)

nsm
nsm

Reputation: 319

You can try with something like this

pv <- c()
for(i in 1:dim(mat1)[2]){
  for(j in 1:dim(mat2)[2]){
    pv <-c(c, cor.test(mat1[, i], mat2[ , j])$estimate)
  }
}

dim(pv) <- c(dim(mat1)[2], dim(mat2)[2])

Upvotes: 0

thelatemail
thelatemail

Reputation: 93938

An alternative, slightly easier to understand than loops in my opinion:

sapply(
  data.frame(mat1),
  function(x) Map(function(a,b) cor.test(a,b)$p.value,
                                list(x),
                                as.data.frame(mat2))
)

Result:

#     X1        X2        X3        X4        X5       
#[1,] 0.7400541 0.8000358 0.5084979 0.4441933 0.9104712
#[2,] 0.2918163 0.2764817 0.956807  0.6072979 0.4395218
#[3,] 0.2866105 0.4095909 0.5648188 0.1746428 0.9125866

Upvotes: 1

tospig
tospig

Reputation: 8343

I think all you need is to define your matrix first

mat_cor <- matrix(nrow=ncol(mat1), ncol=ncol(mat2))
for(i in 1:5)
    {
        for(j in 1:3)
            {
                mat_cor[i,j] <- cor.test(mat1[, i], mat2[ , j])$p.value
            }
    }

Output

mat_cor

          [,1]      [,2]        [,3]
[1,] 0.9455569 0.8362242 0.162569342
[2,] 0.7755360 0.9849619 0.775006329
[3,] 0.8799139 0.8050564 0.001358697
[4,] 0.1574388 0.1808167 0.618624825
[5,] 0.8571844 0.8897125 0.879818822

Upvotes: 0

Athos
Athos

Reputation: 660

I supose you would like to do it without for's. With base stuff, here is the double apply aproach:

apply(mat1, 2, function(col_mat1){
  apply(mat2, 2, function(col2, col1) {
    cor.test(col2, col1)$p.value
  }, col1=col_mat1)
})

The outter apply iterates at mat1 columns and serves one side of cor.test(). The inner one does the same, but now fills the second side of cor.test(). In practie, apply is replacing the for's.

Upvotes: 0

B.Mr.W.
B.Mr.W.

Reputation: 19648

Why don't you just use cor function to calculate the pearson correlation?

seed(1)
mat1 <- matrix(rnorm(20), 4, 5)
mat2 <- matrix(rnorm(12), 4, 3)
cor(mat1, mat2)
       [,1]        [,2]        [,3]
[1,]  0.4406765 -0.70959590  0.10731768
[2,] -0.2566199 -0.01588993 -0.63630159
[3,] -0.9813313  0.85082165 -0.77172317
[4,]  0.6121358 -0.38564314  0.87077092
[5,] -0.6897573  0.66272015 -0.08380553

To double check,

> col_1 <- 3
> col_2 <- 2
# all.equal is used to compare numeric equality where `==` is discouraged
> all.equal(cor(mat1, mat2)[col_1, col_2], cor(mat1[,col_1], mat2[,col_2]))
[1] TRUE

They are equal!

Upvotes: 4

Related Questions