R: Preserve consecutive numbers in matrix -
in vector composed of 0 , 1, '1' should preserved if there @ least 3 consecutive '1'. here example:
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() (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
this works quite me, need perform operation rows of matrix this:
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
to transformed this:
[,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
is there smooth solution?
we can use rle
on logical vector (x==1
), change 'values' lengths
less 3 , 1 'false', use inverse.rle
reconvert original vector.
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
this can applied rows of 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
the above code can made compact without undermining efficiency by
t(apply(m1, 1, fun = function(x) inverse.rle(within.list(rle(x), values[lengths < 3] <- 0))))
note: here calling rle
once , not many times.
data
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))
Comments
Post a Comment