Search code examples
rlistmatrixapplysimplify

Imitate `simplify=F` in `apply()` for versions of R < 4.1.0


Given a binary matrix, I want to generate a list of the positions of the 1s by row. For example:

> M <- matrix(c(1,1,0,0,1,1,1,0,1), 3, 3)
> M
     [,1] [,2] [,3]
[1,]    1    0    1
[2,]    1    1    0
[3,]    0    1    1
> apply(M==1, 1, which, simplify = FALSE)
[[1]]
[1] 1 3

[[2]]
[1] 1 2

[[3]]
[1] 2 3

However, in versions of R before 4.1.0, the apply() function automatically simplifies, which means the result will sometimes not be a list, but gets simplified into a vector or matrix. For example:

> apply(M==1, 1, which)
     [,1] [,2] [,3]
[1,]    1    1    2
[2,]    3    2    3

How can I ensure the output will always be a list, even in earlier versions of R when the simplify = F parameter isn't available for apply()? Thanks!


Solution

  • You can use asplit, which splits the matrix into a list of vectors by the selected margin. Then use lapply on the result to apply the which to each vector.

    lapply(asplit(M == 1, 1), which)
    #> [[1]]
    #> [1] 1 3
    #> 
    #> [[2]]
    #> [1] 1 2
    #> 
    #> [[3]]
    #> [1] 2 3