'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 1:[1]
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
Solution 2:[2]
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
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Allan Cameron |
Solution 2 | akrun |