[R] transposing a distance matrix in R

Steve Lianoglou mailinglist.honeypot at gmail.com
Fri Sep 11 18:48:21 CEST 2009


Hi Jeannine,

I'm just forwarding this Q&A back to the r-help list, you'll get more  
eyes on it and other people might have better solutions.

Answers inline:

On Sep 11, 2009, at 12:25 PM, Jeannine Cavender-Bares wrote:

> Dear Steve,
>
> Greetings! You helped me earlier this summer with an R question in  
> response to a message Brian McCarthy put out on the listserv. I was  
> wondering if you happen to know the answer to the following question  
> or if you can explain how I subscribe to the listserv. Can one just  
> send a message to  r-help at r-project.org?

You can subscribe to the listserv from here:

https://stat.ethz.ch/mailman/listinfo/r-help

> Here goes:
> How does one convert a triangular distance matrix into a single  
> column distance matrix?: e.g.,
>
> traingular:
>    A   B   C
> A na na na
> B 1   na na
> C 0   1   na
>
> single column:
> BA 1
> CA 0
> CB 1

Getting the distances from your matrix is pretty straightforward since  
they're all in the lower triangle of the matrix, see: ?lower.tri

R> m <- matrix(c(NA,1,0,NA,NA,1,NA,NA,NA), 3)
R> dimnames(m) <- list(c('A','B','C'), c('A','B','C'))
R> m[lower.tri(m)]
[1] 1 0 1

Getting the names for the distances is a bit more tricky. I'm trying  
to do that with the "expand.grid" function, check it out to see how it  
works: ?expand.grid

R> who.vs.who <- expand.grid(rownames(m), rownames(m))
R> who.vs.who
   Var1 Var2
1    A    A
2    B    A
3    C    A
4    A    B
5    B    B
6    C    B
7    A    C
8    B    C
9    C    C

We can use the same index generated by ``lower.tri(m)`` to get the  
names of the rows vs cols since R stores the elements of a matrix in  
column major order[1] (note that when I created the matrix ``m``, I  
used a vector that filled a matrix column by column). When you use a  
single integer to index into a matrix, it calculates which position to  
pull out in the same (column major) order, so:

   * ``m[1]`` is really element m[1,1]
   * ``m[2]`` is really element m[2,1], etc ...

So now:

R> who.vs.who[lower.tri(m),]
   Var1 Var2
2    B    A
3    C    A
6    C    B

... almost there, no just put it together:

R> dist <- m[lower.tri(m)]
R> who <- who.vs.who[lower.tri(m),]
R> names(dist) <- paste(who[,1], who[,2], sep=".vs.")
R> dist
B.vs.A C.vs.A C.vs.B
      1      0      1

HTH,
-steve

[1] Column major format: http://en.wikipedia.org/wiki/Row-major_order#Column-major_order

--
Steve Lianoglou
Graduate Student: Computational Systems Biology
   |  Memorial Sloan-Kettering Cancer Center
   |  Weill Medical College of Cornell University
Contact Info: http://cbio.mskcc.org/~lianos/contact




More information about the R-help mailing list