R:保留矩阵中的连续数字

时间:2016-07-11 11:30:24

标签: r matrix

在由0和1组成的向量中,' 1'只有至少有三个连续的' 1才能保留。这是一个例子:

x=c(0,0,0,0,0,1,1,0,1,0,0,1,1,0,1,1,1,0,0,0)

x_consecutive=numeric() 
for (i in 1:20)
  x_consecutive[i]=((x[i]>0) & (x[i+1]>0) & (x[i+2]>0)) | ((x[i]>0) & (x[i+1]>0) & (x[i-1]>0)) | ((x[i]>0) & (x[i-1]>0) & (x[i-2]>0)) 

x_consecutive
 [1] NA NA  0  0  0  0  0  0  0  0  0  0  0  0  1  1  1  0  0  0

这对我来说效果很好,但我需要对矩阵的所有行执行此操作,如下所示:

matrix(sample(c(0:1),50, replace=T), nrow=5, ncol=10)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]    1    1    1    1    1    0    1    1    0     1
[2,]    0    0    0    0    0    1    1    1    0     0
[3,]    1    1    1    1    0    0    1    1    1     0
[4,]    1    0    0    1    0    0    0    0    1     1
[5,]    0    0    0    1    1    0    1    1    0     0

转变为:

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]    1    1    1    1    1    0    0    0    0     0
[2,]    0    0    0    0    0    1    1    1    0     0
[3,]    1    1    1    1    0    0    1    1    1     0
[4,]    0    0    0    0    0    0    0    0    0     0
[5,]    0    0    0    0    0    0    0    0    0     0

有一些顺利的解决方案吗?

2 个答案:

答案 0 :(得分:3)

我们可以在逻辑向量(rle)上使用x==1,更改lengths小于3且“1”为“FALSE”的“值”,使用{{ 1}}将其重新转换回原始矢量。

inverse.rle

这可以应用于x1 <- as.integer(inverse.rle(within.list(rle(x==1), values[lengths < 3 & values] <- FALSE))) x1 #[1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 matrix

的所有行
apply

上述代码也可以在不损害效率的情况下轻松实现

t(apply(m1, 1, FUN = function(x) as.integer(inverse.rle(within.list(rle(x==1), 
         values[lengths < 3 & values] <- FALSE)))))
#    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#[1,]    1    1    1    1    1    0    0    0    0     0
#[2,]    0    0    0    0    0    1    1    1    0     0
#[3,]    1    1    1    1    0    0    1    1    1     0
#[4,]    0    0    0    0    0    0    0    0    0     0
#[5,]    0    0    0    0    0    0    0    0    0     0

注意:这里我只调用t(apply(m1, 1, FUN = function(x) inverse.rle(within.list(rle(x), values[lengths < 3] <- 0)))) 一次而不是多次。

数据

rle

答案 1 :(得分:0)

使用@ akrun&#39; s m1的另一种方法可能

t(apply(m1,1,function(t) rep(ifelse(rle(t)$lengths>2,1,0),rle(t)$lengths)))

t(apply(m1,1, function(t) with(rle(t), rep(as.integer(lengths>2),lengths))))