user1577603
user1577603

Reputation: 21

Combining a matrix of TRUE/FALSE into one

If I have this matrix (which I named data):

     [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9]
[1,] FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE
[2,] FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE
[3,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[4,] FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE
[5,] FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE
[6,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[7,] FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE
[8,] FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE
[9,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

And I want to combine the columns into one single column like this: (where one TRUE in the row equals TRUE)

      [,1]   
 [1,] TRUE 
 [2,] TRUE 
 [3,] FALSE 
 [4,] TRUE   
 [5,] TRUE 
 [6,] FALSE  
 [7,] TRUE   
 [8,] TRUE  
 [9,] FALSE  

I know I could do something like (using the |):

  data2[1:9,1]<-data[,1]|data[,2]|data[,3]|data[,4]…

data2 would then contain a single column with the different columns combined. But this is not a good way if I would have lots of columns (for example ncol=100)

I guess there is some simple way of doing it?

Thanks

Upvotes: 2

Views: 1695

Answers (2)

flodel
flodel

Reputation: 89057

Here is another answer that takes advantage of how R converts between logicals and numerics:

When going from logical to numeric, FALSE becomes 0 and TRUE becomes 1 so rowSums gives you the number of TRUE per row:

rowSums(data)
# [1] 3 3 0 3 3 0 3 3 0

When going from numeric to logical, 0 becomes FALSE, anything else is TRUE, so you can feed the output of rowSums to as.logical and it will indicate if a row has at least one TRUE:

as.logical(rowSums(data))
# [1]  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE

I like Tyler's answer though, it might be less efficient (to be proven) but I find it more intuitive.

Upvotes: 9

Tyler Rinker
Tyler Rinker

Reputation: 109864

You could use any with apply as in:

mat <- matrix(sample(c(TRUE, FALSE), 100,TRUE), 10)
apply(mat, 1, any)

Upvotes: 5

Related Questions