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

Time:03-19

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!

CodePudding user response:

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

CodePudding user response:

We may use which with arr.ind = TRUE and then split by the 'row'

ind <- which(M == 1, arr.ind = TRUE)
split(ind[,2], ind[, 1])
$`1`
[1] 1 3

$`2`
[1] 1 2

$`3`
[1] 2 3
  • Related