R:在矩阵中保留连续数

R:在矩阵中保留连续数,r,matrix,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-

在由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

有平滑的解决方案吗?

我们可以对逻辑向量(
x==1
)使用
rle
),将
长度小于3且为1的“值”更改为“假”,使用
反向.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
上述代码也可以稍微紧凑一些,而不会降低效率

t(apply(m1, 1, FUN = function(x) inverse.rle(within.list(rle(x),
                 values[lengths < 3] <- 0))))

另一种方法是使用@akrun的
m1
maybe

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

m1 <- structure(c(1L, 0L, 1L, 1L, 0L, 1L, 0L, 1L, 0L, 0L, 1L, 0L, 1L, 
0L, 0L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 1L, 0L, 1L, 0L, 0L, 
0L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 1L, 0L, 0L, 1L, 1L, 0L, 
1L, 0L, 0L, 1L, 0L), .Dim = c(5L, 10L))
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))))