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

Time:02-08

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?

CodePudding user response:

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

CodePudding user response:

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

# $`2`
# [1] 2

# $`3`
# [1] 3
  •  Tags:  
  • Related