Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R: how to get row and column names of the true elements of a matrix?

Tags:

r

I have a logical matrix x with named rows ('a' and 'b') and named columns ('10', '20', '30', '40'). Let's say, this:

   10   20   30   40  
a  T    F    T    F  
b  F    T    F    T  

structure(c(TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE),
.Dim = c(2L, 4L), .Dimnames = list(c("a", "b"), c("10", "20", "30", "40")))

Is there a short way to get a table that would list names of rows and columns where I have true values? That is, I want to get the following table:

a  10, 30
b  20, 40

Something similar can be obtained by which(x, arr.ind = T), which produces

  row col
a   1   1
b   2   2
a   1   3
b   2   4

But I really want to get the first table.

like image 922
Leo Avatar asked Feb 29 '12 20:02

Leo


2 Answers

You can directly use apply.

apply(
  x, 1, 
  function(u) paste( names(which(u)), collapse="," ) 
)
like image 193
Vincent Zoonekynd Avatar answered Oct 04 '22 14:10

Vincent Zoonekynd


You didn't specify this, but your desired output will require that we assume that the result is in fact rectangular. Namely, that we don't get 3 column names for a and only 2 column names for b.

I think this should get you started, at least:

m <- structure(c(TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE),
.Dim = c(2L, 4L), .Dimnames = list(c("a", "b"), c("10", "20", "30", "40")))

rr <- rownames(m)[row(m)[which(m)]]
cc <- colnames(m)[col(m)[which(m)]]

dd <- data.frame(rr = rr,cc = cc)
dd

which returns the information you want, but in a safer "long" format, which won't choke on the non-rectangular case. Once there, you could re-organize it as you specified like this:

library(plyr)
ddply(dd,.(rr),function(x){ x$cc })

but frankly that last bit I find really ugly, and I wouldn't be surprised if a better solution pops up if you wait a bit.

like image 38
joran Avatar answered Oct 04 '22 14:10

joran