在由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
有一些顺利的解决方案吗?
答案 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))))