我有一个看起来像这样的二进制编码矩阵(0/1)矩阵:
X1 X2 X3 X4
1 1 0 0 1
2 0 0 0 0
3 0 0 0 0
4 1 1 1 0
5 1 1 0 0
6 0 0 1 0
7 1 0 1 0
8 0 0 1 0
9 0 0 1 0
10 0 0 0 0
11 1 1 0 0
12 0 0 0 1
13 0 0 0 1
14 0 0 0 1
15 0 0 0 0
16 0 1 1 0
17 1 1 0 0
18 1 0 1 0
19 1 0 1 0
20 1 1 1 1
我正在寻找一种我可以直观地确定和描述但无法通过程序搜索来找到该模式的模式。这是模式:
我想找到编号 1 的运行结束,该运行停止并由不同的列在下一行中拾取(如果这些列碰巧并排,则为对角线开关)。如果另一列将保持这种 1 的运行,则对角线开关不计算在内。
所以在上面的矩阵中,对角线切换发生在 x[5, 2] 到 x[6, 3] 并再次发生在 x[11, 1 (或 2)] 到 x[12, 4]
x <- structure(list(X1 = c(1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0,
0, 0, 0, 1, 1, 1, 1), X2 = c(0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1,
0, 0, 0, 0, 1, 1, 0, 0, 1), X3 = c(0, 0, 0, 1, 0, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1), X4 = c(1L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 1L)), .Names = c("X1",
"X2", "X3", "X4"), row.names = c(NA, -20L), class = "data.frame")
这是一个很难描述的问题,但我想我已经用这个例子来说明它了。所需的输出将是c(5, 11)
因为这些是 1 具有此模式时的行。
我怀疑rle
并且cumsum
可能在这里有用。
编辑为问题添加信息。我在不同的矩阵上尝试了 Ricardo 的初始解决方案:
X1 X2 X3 X4 X5
1 0 0 1 0 0
2 1 1 0 0 1
3 0 0 0 0 0
4 0 0 1 0 0
5 0 1 1 0 0
6 1 0 1 1 0
7 1 1 0 0 0
8 0 0 1 1 1
9 0 0 1 0 0
10 1 1 0 1 0
rowdiffs <- apply(D, 2, diff)
N <- rowSums(rowdiffs==-1)
P <- rowSums(rowdiffs==1)
which(N - P > 0 & P > 0)
它给:
## 7
## 6
我希望c(1, 7, 9)
可以在此处追踪的行中看到。在每个红点处,我别无选择,只能走对角线(这些是蓝色路径)。如果我到达一行全 0(黄色框),我跳过该行并从下一行的路径(路径为橙色)重新开始(并且没有记录对角线模式)
D <- structure(list(X1 = c(0L, 1L, 0L, 0L, 0L, 1L, 1L, 0L, 0L, 1L),
X2 = c(0L, 1L, 0L, 0L, 1L, 0L, 1L, 0L, 0L, 1L), X3 = c(1L,
0L, 0L, 1L, 1L, 1L, 0L, 1L, 1L, 0L), X4 = c(0L, 0L, 0L, 0L,
0L, 1L, 0L, 1L, 0L, 1L), X5 = c(0L, 1L, 0L, 0L, 0L, 0L, 0L,
1L, 0L, 0L)), .Names = c("X1", "X2", "X3", "X4", "X5"), row.names = c(NA,
10L), class = "data.frame")