如何用零和1计算矩阵中对角线(由1组成)的数量

Mar*_*ark 1 r matrix

我有矩阵的每个单元格中随机分配0或1的矩阵.5乘5矩阵可能如下所示:

A
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    1    0    1
[2,]    0    0    1    0    1
[3,]    0    1    1    1    1
[4,]    1    1    0    1    1
[5,]    1    1    0    1    0
Run Code Online (Sandbox Code Playgroud)

例如,由代码生成:

mm <- matrix(0, 5, 5)
A<-apply(mm, c(1, 2), function(x) sample(c(0, 1), 1))
Run Code Online (Sandbox Code Playgroud)

对角线由以下方式组成1:

在此输入图像描述

即,有3条长度为2的对角线和2条长度为3的对角线.此外,没有长度为4和5的对角线.

我会将此结果存储在一个数组中v:

v
[1] 3 2 0 0
Run Code Online (Sandbox Code Playgroud)

v[1]存储长度为2的v[2]对角线,存储长度为3的对角线,依此类推.

我的尝试错了.它基于:

which(A!=0)
 [1]  4  5  8  9 10 11 12 13 18 19 20 21 22 23 24
Run Code Online (Sandbox Code Playgroud)

在这个数组中:

4 8 12
Run Code Online (Sandbox Code Playgroud)

5 9 13
Run Code Online (Sandbox Code Playgroud)

对应于长度为3的2条对角线.长度为2的3条对角线为:

18 22
19 23
20 24
Run Code Online (Sandbox Code Playgroud)

(我检查了相差4的数字).但是如果有所有1的列,则此方法不起作用(尝试使用A[5,5]<-1).

G. *_*eck 5

row(A) + col(A) 在antidiagonals上是恒定的,所以:

tabulate_runs <- function(x, n) {
  tab <- with(rle(x), tabulate(lengths[values == 1]))
  replace(integer(n), seq_along(tab), tab)
 }
rowSums(simplify2array(tapply(A, row(A) + col(A), tabulate_runs, nrow(A))))[-1]
## [1] 3 2 0 0
Run Code Online (Sandbox Code Playgroud)

注意

A在问题中产生的代码是不可重现的,因为它使用随机数而不设置种子,所以为了再现性,我们使用了这个:

A <- structure(c(0L, 0L, 0L, 1L, 1L, 0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 
0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L), .Dim = c(5L, 
5L))
Run Code Online (Sandbox Code Playgroud)