【问题标题】:rle for finding rectangles in matrixrle 用于在矩阵中查找矩形
【发布时间】:2014-08-31 13:20:54
【问题描述】:

我正在按照这种方法在 (0,1) 矩阵中查找 1 的矩形

Find 5 consecutive numbers >= 3 for each row of a matrix

但是当我尝试在这个矩阵中找到 1x4 矩形(1 行和 4 列)时出现问题

m <- matrix(c(0,1,1,1,1,0,0,0,1,0,1,0,0,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0), nrow = 6, ncol = 5, byrow = TRUE)

有四个矩形:第 1 行、第 4 行、第 5 行和第 6 行

   [,1] [,2] [,3] [,4] [,5]
[1,]    0    1    1    1    1
[2,]    0    0    0    1    0
[3,]    1    0    0    1    0
[4,]    1    1    1    1    0
[5,]    0    1    1    1    1
[6,]    1    1    1    1    0

当我为这种情况运行代码时,我得到了 4 个结果,但其中两个(第 4 行和第 6 行)都从第一列开始,但结果我得到第 5 列的起始列和第 8 列的结束列矩阵是 6x5,无法找出问题所在。

b<-m

for (j in 1:5){
cont<-1
 for (i in 6:1) {
 if (m[i,j]==0){
cont<-1
b[i,j]<-NA}
 else {b[i,j]<-cont
cont<-cont+1}
}
}


mdat<-b

apply(mdat, 1, function(x) {
  r <- rle(x >= 1)
  w <- which(!is.na(r$values) & r$values & r$lengths >=4)
  if (length(w) > 0) {
    before <- sum(r$lengths[1:(w[1]-1)])
    c(before+1,before+ r$lengths[w[1]])
  } else
    NULL
})

[[1]]
[1] 2 5

[[2]]
NULL

[[3]]
NULL

[[4]]
[1] 5 8

[[5]]
[1] 2 5

[[6]]
[1] 5 8

【问题讨论】:

  • 您将什么定义为“矩形”?您的意思是连续 4 个 1 在一行中?
  • 是的,对我来说它是一个 1x4 矩形

标签: r matrix


【解决方案1】:

您需要更改 before 变量的计算,因为如果行以 1 的序列开头,则它不起作用:

apply(mdat, 1, function(x) {
  r <- rle(x >= 1)
  w <- which(!is.na(r$values) & r$values & r$lengths >=4)
  if (length(w) > 0) {
    before <- sum(r$lengths[1:w[1]]) - r$lengths[w[1]]
    c(before+1,before+r$lengths[w[1]])
  } else
    NULL
})

问题出在下面一行:

before <- sum(r$lengths[1:(w[1]-1)])

只有当序列不在第一个位置(即 w > 1)时才能正常工作。

顺便说一句,请注意,您的代码仅考虑该行中的第一个序列,而忽略其他序列(如果存在)。
例如假设有一个矩阵row = c(0,1,1,1,1,0,1,1,1,1),它将只返回c(2,5) 而不是c(2,5), c(7,10)

如果你想要返回所有序列的东西,你可以使用这个代码:

apply(mdat, 1, function(x) {
  r <- rle(x >= 1)
  w <- which(!is.na(r$values) & r$values & r$lengths >=4)
  if (length(w) > 0) {
    lapply(w,FUN=function(w1){ before <- sum(r$lengths[1:w1]) - r$lengths[w1];
                               c(before+1,before+r$lengths[w1]) })
  } else
    NULL
})

注意它返回一个列表,其中每个元素都是一个包含对的列表

【讨论】:

  • 非常感谢!!如果不是在行中查找序列,而是尝试在列中查找它们,例如在上面的矩阵中,第四列中有 6 个连续的 1,我使用相同的 mdat 矩阵和相同的代码,但更改 >= 条件是不够
  • 嗯,有一个简单的“hack”,即将转置矩阵传递给应用程序(只需执行 t(mdat) 即可获得转置矩阵)。但是,如果您想正确更改代码以在列上工作,请将传递给 apply 的第二个参数从 1 更改为 2(1 表示“为每一行应用函数”,2 表示“为每一行应用函数”)
  • 对不起,我刚刚注意到一个愚蠢的复制和粘贴错误......显然它是:1 表示“每行应用函数”,2 表示“每列应用函数”我>。但我想你还是明白了:)
猜你喜欢
  • 1970-01-01
  • 2014-01-01
  • 1970-01-01
  • 2020-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多