3

我有一个看起来像这样的二进制编码矩阵(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")
4

2 回答 2

3

尝试以下操作:

rowdiffs <- rbind(apply(D, 2, diff), NA)

N  <- rowSums(rowdiffs==-1)
P  <- rowSums(rowdiffs==1)

candidates <- which(N &  P)
falseCandidates <- which(rowSums(rowdiffs==0 & D==1) >= 1)

setdiff(candidates, falseCandidates)
#  [1] 1 7 9

解释:

将每一行与其下面的行进行比较 ( rowdiffs)。
候选行将具有以下属性:

* contain both a `-1` and `+1` in the diffs 
      (indicating the diagonal move)
* NOT contain a `0` in the diffs where there is a `1` in the original data
      (indicating potential lateral move (or standard straight down))
于 2013-09-23T03:03:59.790 回答
1

您的图表(1,7,9)中的虚线行可以通过以下方式找到:

trans <- apply(D, 2, function(x) head(x,-1)*10+tail(x,-1))

which(apply(trans, 1, function(y) (1 %in% y) && (10 %in% y) && !(11 %in% y) ))

#1 7 9 

解释:首先建立一个转换矩阵,然后找到从 0 到 1 和从 1 到 0 的转换都发生的行,但没有出现连续的行。

于 2013-09-23T03:05:30.370 回答