Учитывая двоичную матрицу, я хочу сгенерировать список позиций 1 по строке. Например:
> 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
Однако в версиях R до 4.1.0 функция apply()
автоматически упрощается, что означает, что результатом иногда будет не список, а упрощение до вектора или матрицы. Например:
> apply(M==1, 1, which)
[,1] [,2] [,3]
[1,] 1 1 2
[2,] 3 2 3
Как я могу гарантировать, что на выходе всегда будет список, даже в более ранних версиях R, когда параметр simplify = F
недоступен для apply()
? Спасибо!
Вы можете использовать asplit
, который разбивает матрицу на список векторов по выбранному краю. Затем используйте lapply
на результате, чтобы применить which
к каждому вектору.
lapply(asplit(M == 1, 1), which)
#> [[1]]
#> [1] 1 3
#>
#> [[2]]
#> [1] 1 2
#>
#> [[3]]
#> [1] 2 3
Работает отлично и лишь незначительно медленнее, чем при использовании apply(simplify=T)
. Спасибо!
Мы можем использовать which
с arr.ind = TRUE
, а затем split
рядом с «строкой».
ind <- which(M == 1, arr.ind = TRUE)
split(ind[,2], ind[, 1])
$`1`
[1] 1 3
$`2`
[1] 1 2
$`3`
[1] 2 3
Я изменил пример в исходном сообщении на случай, когда это решение не сработает.