You might try gathering all consecutive values (left to right, top to bottom, and diagonal) in a list and then call rle
on each list element. For example, using the following data:
set.seed(30948)
mat <- matrix(rbinom(10 * 5, 1, 0.5), ncol = 20, nrow = 20)
Combine rows, columns, and bottom-left and top-right diagonals in consecs
, then call rle
on each element and return the sum. I retrieve all the diagonals by calling diag
on subsets of mat
. Note that the corners are ignored because of 1:(ncol(mat)-1)
, and that I drop the first diagonal of the bottom-left corner with [-1]
because it is already extracted in the prior lapply
:
consecs <- c(lapply(1:ncol(mat), function(x) mat[, x]),
lapply(1:nrow(mat), function(x) mat[x, ]),
lapply(1:(ncol(mat)-1), function(x) diag(mat[, x:ncol(mat)])),
lapply(1:(nrow(mat)-1), function(x) diag(mat[x:nrow(mat), ]))[-1]
)
sum(sapply(consecs, function(x) with(rle(x), sum(lengths[values == 1] > 5))))
#[1] 14
Edit:
I gather from your comments that you want apply the above code to a list of matrices. To do that just put the code in a function and pass it into lapply
:
# Create a list of matrices.
set.seed(30948)
mat_list <- list(mat1 = matrix(rbinom(10 * 5, 1, 0.5), ncol = 20, nrow = 20),
mat2 = matrix(rbinom(10 * 5, 1, 0.5), ncol = 20, nrow = 20),
mat3 = matrix(rbinom(10 * 5, 1, 0.5), ncol = 20, nrow = 20)
)
# Put the above code in a function.
compute_consecs <- function(mat){
consecs <- c(lapply(1:ncol(mat), function(x) mat[, x]),
lapply(1:nrow(mat), function(x) mat[x, ]),
lapply(1:(ncol(mat)-1), function(x) diag(mat[, x:ncol(mat)])),
lapply(1:(nrow(mat)-1), function(x) diag(mat[x:nrow(mat), ]))[-1]
)
sum(sapply(consecs, function(x) with(rle(x), sum(lengths[values == 1] > 5))))
}
# Apply the function to your list of matrices.
lapply(mat_list, compute_consecs)
#### OUTPUT ####
$mat1
[1] 14
$mat2
[1] 0
$mat3
[1] 7