Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert binary matrix to column-indexed lists by row in R

Tags:

list

r

matrix

Given a binary matrix B, I can usually get a list of the column indexes of the 1s by row using Blist <- apply(B==1, 1, which). However, this doesn't work when, for example, rowSums(B)[1] == rowSums(B)[2].

Here's an example where it works:

> B <- matrix(c(1,1,0,0,1,0,0,0,1),3,3)
> B
     [,1] [,2] [,3]
[1,]    1    0    0
[2,]    1    1    0
[3,]    0    0    1
> Blist <- apply(B==1, 1, which)
> Blist
[[1]]
[1] 1

[[2]]
[1] 1 2

[[3]]
[1] 3

Here's an example when it doesn't work:

> B <- matrix(c(1,0,0,0,1,0,0,0,1),3,3)
> B
     [,1] [,2] [,3]
[1,]    1    0    0
[2,]    0    1    0
[3,]    0    0    1
> Blist <- apply(B==1, 1, which)
> Blist
[1] 1 2 3

In this case, the desired result is:

> Blist
[[1]]
[1] 1

[[2]]
[1] 2

[[3]]
[1] 3

How can I modify Blist <- apply(B==1, 1, which) so that the result is always organized as a list?

like image 847
Zachary Avatar asked Oct 25 '25 17:10

Zachary


2 Answers

There is simplify argument which is TRUE by default. The default usage from ?apply`

apply(X, MARGIN, FUN, ..., simplify = TRUE)

simplify - a logical indicating whether results should be simplified if possible.

Also, it states

If the calls to FUN return vectors of different lengths, or if simplify is FALSE, apply returns a list of length prod(dim(X)[MARGIN]) with dim set to MARGIN if this has length greater than one.

apply(B==1, 1, which, simplify = FALSE)
[[1]]
[1] 1

[[2]]
[1] 2

[[3]]
[1] 3
like image 153
akrun Avatar answered Oct 27 '25 07:10

akrun


m = which(B == 1, arr.ind=TRUE)
split(m[,"col"], m[,"row"])
# $`1`
# [1] 1

# $`2`
# [1] 2

# $`3`
# [1] 3
like image 44
d.b Avatar answered Oct 27 '25 06:10

d.b



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!