Пытаетесь найти число диагоналей 1 в каждой ячейке 3x3 в двоичной матрице 15x15? - PullRequest
1 голос
/ 27 октября 2019

Я пытаюсь найти количество диагональных 1 с в каждой ячейке 3x3, например

0 0 1         1 0 0
0 1 0         0 1 0
1 0 0    or   0 0 1

из приведенной ниже матрицы 15x15.

set.seed(99)
mat <- matrix(sample(c(0,1), 225, prob=c(0.8,0.2), replace=TRUE), nrow=15)
print(mat)

    [,1][,2][,3][,4][,5][,6][,7][,8][,9][,10][,11][,12][,13][,14][,15]
[1,]  0   0   1   0   0   0   0   0   0    0    0    0    0    0   0
[2,]  0   1   0   1   0   0   1   0   0    0    1    0    0    0   1
[3,]  0   0   0   1   0   0   0   0   1    0    0    1    0    0   0
[4,]  0   0   0   0   0   0   0   1   1    0    0    0    0    0   1
[5,]  0   0   0   0   1   0   0   1   1    1    0    0    0    0   0
[6,]  0   0   0   0   0   0   1   0   0    0    0    0    1    0   0
[7,]  0   0   0   0   0   0   0   0   0    0    0    0    0    0   0
[8,]  0   0   0   0   0   0   0   1   0    1    0    0    0    0   0
[9,]  0   0   0   0   0   1   0   0   1    1    0    0    1    0   1
[10,] 0   0   0   0   0   0   0   0   1    0    1    1    0    1   0
[11,] 0   0   0   0   0   0   1   0   0    1    0    1    0    0   0
[12,] 0   0   0   0   0   0   1   0   0    1    0    0    0    0   0
[13,] 0   0   0   0   0   1   0   1   0    0    1    0    1    0   0
[14,] 1   1   0   1   1   0   0   0   0    1    0    0    0    0   1
[15,] 1   0   1   0   1   1   0   0   0    1    0    1    0    0   0

Я ожидаю, что на выходе будет 2 длявышеуказанная матрица. Есть ли способ сделать это с помощью цикла for и операторов if?

Ответы [ 2 ]

1 голос
/ 27 октября 2019

Мы могли бы использовать outer(). Для этого мы напишем две маленькие векторизованные функции, которые подсчитывают элементы диагонали среза 3x3 нашей матрицы;если sum равно 3, у нас есть правильная диагональ.

Для контрдиагонали мы заимствуем код из этого решения .

counterdiag <- function(M) M[(n<-nrow(M))^2-(1:n)*(n-1)]

Теперь все, что нам нужноэто некоторые координаты.

m <- n <- mapply(function(i) i:(i+2), 1:13)

И наши функции подсчета.

fun1 <- Vectorize(function(x, y) sum(diag(mat[m[,x], n[,y]])) == 3, SIMPLIFY=FALSE)
fun2 <- Vectorize(function(x, y) sum(counterdiag(mat[m[,x], n[,y]])) == 3, SIMPLIFY=FALSE)

Использование

sum(unlist(outer(1:13, 1:13, fun1)))  # diagonals
# [1] 1

sum(unlist(outer(1:13, 1:13, fun2)))  # counterdiagonals
# [1] 3
0 голосов
/ 27 октября 2019

Вот вложенный цикл (используя 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...