Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to extract values between adjacent variables in a correlation matrix in R?

Tags:

r

filter

matrix

I have got huge correlation matrix, but the following is just an example:

    set.seed(1234)

corrmat <- matrix(round (rnorm (36, 0, 0.3),2), ncol=6) 
rownames (corrmat) <- colnames (corrmat) <- c("A", "b1", "b2", "C", "L", "ctt")
diag(corrmat) <- NA 
corrmat[upper.tri (corrmat)] <- NA 
            A    b1    b2     C     L ctt
    A      NA    NA    NA    NA    NA  NA
    b1   0.08    NA    NA    NA    NA  NA
    b2   0.33 -0.17    NA    NA    NA  NA
    C   -0.70 -0.27 -0.03    NA    NA  NA
    L    0.13 -0.14 -0.15 -0.13    NA  NA
    ctt  0.15 -0.30 -0.27  0.14 -0.28  NA

> melt(corrmat)

       X1  X2  value
    1    A   A    NA
    2   b1   A  0.08
    3   b2   A  0.33
    4    C   A -0.70
    5    L   A  0.13
    6  ctt   A  0.15
    7    A  b1    NA
    8   b1  b1    NA
    9   b2  b1 -0.17
    10   C  b1 -0.27
    11   L  b1 -0.14
    12 ctt  b1 -0.30
    13   A  b2    NA
    14  b1  b2    NA
    15  b2  b2    NA
    16   C  b2 -0.03
    17   L  b2 -0.15
    18 ctt  b2 -0.27
    19   A   C    NA
    20  b1   C    NA
    21  b2   C    NA
    22   C   C    NA
    23   L   C -0.13
    24 ctt   C  0.14
    25   A   L    NA
    26  b1   L    NA
    27  b2   L    NA
    28   C   L    NA
    29   L   L    NA
    30 ctt   L -0.28
    31   A ctt    NA
    32  b1 ctt    NA
    33  b2 ctt    NA
    34   C ctt    NA
    35   L ctt    NA
    36 ctt ctt    NA

What I am looking is correlation values between adjacent only - means that between A-b1, b1-b2,b2-C, C-L, L-ctt (in the order in column). I need to remove other values and NA. Thus expected will be:

        X1   X2  value
    2   b1   A   0.08
    9   b2   b1 -0.17
    16   C   b2  -0.03
    23   L   C  -0.13
    30  ctt  L  -0.28

Thus they are in: A-b1-b2-C-L-ctt order.

Is there a easy way to filter it ?

like image 313
shNIL Avatar asked Aug 02 '12 20:08

shNIL


2 Answers

Here is one way using the often overlooked functions row() and col()

> corrmat ## my version as there was no set.seed
        A    b1    b2    C     L ctt
A      NA    NA    NA   NA    NA  NA
b1   0.03    NA    NA   NA    NA  NA
b2  -0.41 -0.02    NA   NA    NA  NA
C    0.11  0.61 -0.18   NA    NA  NA
L   -0.28 -0.28  0.39 0.01    NA  NA
ctt -0.21 -0.41 -0.55 0.34 -0.13  NA

> corrmat[row(corrmat) == col(corrmat) + 1]
[1]  0.03 -0.02 -0.18  0.01 -0.13

Note that we are indexing the matrix corrmat as a vector here, and the bit in the brackets says return elements where the row index of each element matches the column index of each element plus 1. Using -1 would give you the superdiagonal (i.e. above the diagonal).

To put it all together:

out <- data.frame(X1 = rownames(corrmat)[-1],
                  X2 = head(colnames(corrmat), -1),
                  Value = corrmat[row(corrmat) == col(corrmat) + 1])

> out
   X1 X2 Value
1  b1  A  0.03
2  b2 b1 -0.02
3   C b2 -0.18
4   L  C  0.01
5 ctt  L -0.13
like image 191
Gavin Simpson Avatar answered Oct 12 '22 04:10

Gavin Simpson


Here's one way:

n = rownames(corrmat)
pair.table = data.frame(X1=head(n, -1), X2=tail(n, -1), value=diag(tail(corrmat, -1)))

Result:

> pair.table
  X1  X2 value
1  A  b1  0.08
2 b1  b2 -0.17
3 b2   C -0.03
4  C   L -0.13
5  L ctt -0.28
like image 29
David Robinson Avatar answered Oct 12 '22 04:10

David Robinson