Вот вложенный цикл (используя sapply()
). Обратите внимание, что у меня не было того же набора данных, что и у вас, поэтому есть другое начальное число.
set.seed(123)
mat <- matrix(sample(c(0,1), 225, prob=c(0.8,0.2), replace=TRUE), nrow=15)
n_by_n <- 3L
reg_diag <- diag(n_by_n)
rev_diag <- reg_diag[nrow(reg_diag):1, ]
sum(
sapply(seq_len(ncol(mat)- n_by_n + 1),
function(col) {
sapply(seq_len(nrow(mat) - n_by_n + 1),
function(row) {
tmp <- mat[row:(row + n_by_n - 1), col:(col + n_by_n - 1)]
all(tmp == reg_diag) | all(tmp == rev_diag)
})
})
)
#[1] 1
Если вас интересуют только диагонали, и вас не интересуют другие значения в подматрице, это разбивает матрицу на каждуюдиагонали, а затем вычислили скользящую сумму, чтобы увидеть, составляют ли они до 3:
library(RcppRoll)
set.seed(99)
mat <- matrix(sample(c(0,1), 225, prob=c(0.8,0.2), replace=TRUE), nrow=15)
n_by_n <- 3
diags <- row(mat)- col(mat)
cross_diags <- row(mat) + col(mat)
#could use data.table::frollsum instead of RcppRoll::roll_sumr)
sum(unlist(lapply(split(mat, diags), RcppRoll::roll_sumr, n_by_n), use.names = F) == n_by_n, na.rm = T)
#[1] 1
sum(unlist(lapply(split(mat, cross_diags), RcppRoll::roll_sumr, n_by_n), use.names = F) == n_by_n, na.rm = T)
# [1] 3
Полный базовый подход будет выглядеть так:
base_rollr <- function(x, roll) {
#from user @flodel
if (length(x) >= roll) tail(cumsum(x) - cumsum(c(rep(0, roll), head(x, -roll))), -roll + 1)
}
sum(unlist(lapply(split(mat, cross_diags), base_rollr, n_by_n), use.names = F) == n_by_n, na.rm = T)
См. также: Получить всю диагональвекторы из матрицы
А: Последовательные / Скользящие суммы в векторе в R