Я буду использовать небольшую матрицу 3x3 для иллюстрации метода.
m <- matrix(c(0, 0, 1, 1, 1, 1, 1, 1, 0), nrow = 3)
m
#> [,1] [,2] [,3]
#> [1,] 0 1 1
#> [2,] 0 1 1
#> [3,] 1 1 0
Мы будем использовать пакет matrixcalc
, в частности его функции shift.*
для вычисления количества 1-соседейкаждой клетки. Например, давайте посмотрим на shif.up(m)
.
library(matrixcalc)
m_u <- shift.up(m)
m_u
#> [,1] [,2] [,3]
#> [1,] 0 1 1
#> [2,] 1 1 0
#> [3,] 0 0 0
Это просто m
, поднятый вверх с нижним рядом, заполненным нулями. Основная идея здесь заключается в том, что для любых заданных индексов (i, j), если матрица m_u
имеет 1
в этом месте, это означает, что эта ячейка в исходной матрице имеет 1
-конечность внизу. Аналогичная логика применима ко всем другим сменам. Итак, чтобы вычислить число 1
соседей во всех 8 направлениях, мы должны суммировать все 8 сдвиговых матриц.
mat_neighbours <- function(m) {
# up, down, left, right shifts
m_u <- shift.up(m)
m_d <- shift.down(m)
m_l <- shift.left(m)
m_r <- shift.right(m)
# diagonal shifts
m_ul <- shift.left(m_u)
m_ur <- shift.right(m_u)
m_dl <- shift.left(m_d)
m_dr <- shift.right(m_d)
m_u + m_d + m_l + m_r +
m_ul + m_ur + m_dl + m_dr
}
mat_neighbours(m)
#> [,1] [,2] [,3]
#> [1,] 2 3 3
#> [2,] 4 5 4
#> [3,] 2 3 3
Здесь мы можем видеть, например, что ячейка (2, 2) в m
имеет 5 1
соседей.
Имея эту функцию, теперь легко вычислить количество 1
ячеек с 5 или более 1
соседями.
sum((m == 1) & mat_neighbours(m) >= 5)
#> [1] 1
Чтобы применить его к вашему списку файлов:
library(purrr)
temp %>%
map(read.table) %>%
map(as.matrix) %>%
map_dbl(~sum((. == 1) & mat_neighbours(.) >= 5))