I need to reduce the consecutive NA's in a vector to a single NA, without touching the other values.
So, for example, given a vector like this:
NA NA 8 7 NA NA NA NA NA 3 3 NA -1 4
what I need to get, is the following result:
NA 8 7 NA 3 3 NA -1 4
Currently, I'm using the following function:
reduceConsecutiveNA2One <- function(vect){
enc <- rle(is.na(vect))
# helper func
tmpFun <- function(i){
if(enc$values[i]){
data.frame(L=c(enc$lengths[i]-1, 1), V=c(TRUE,FALSE))
}else{
data.frame(L=enc$lengths[i], V=enc$values[i])
}
}
Df <- do.call(rbind.data.frame,lapply(1:length(enc$lengths),FUN=tmpFun))
return(vect[rep.int(!Df$V,Df$L)])
}
and it seems to work fine, but probably there's a simpler/faster way to accomplish this task.
Any suggestions ?
Thanks in advance.
Here's one idea:
x <- c(NA, NA,8,7,NA, NA, NA, NA, NA, 3, 3, NA, -1, 4)
x[!(is.na(x) & diff(c(FALSE, is.na(x)))==0)]
# [1] NA 8 7 NA 3 3 NA -1 4
## It also works for length-one vectors
x <- NA
x[!(is.na(x) & diff(c(FALSE, is.na(x)))==0)]
# [1] NA
Maybe this could be useful
x <- c(NA, NA,8,7,NA, NA, NA, NA, NA, 3, 3, NA, -1, 4)
c(x[rowSums(is.na(embed(x,2)))!=2], x[length(x)])
[1] NA 8 7 NA 3 3 NA -1 4
If you want a function try:
myfun <- function(x){
if(length(x)==1) {
return(x)
}
else{
return(c(x[rowSums(is.na(embed(x,2)))!=2], x[length(x)]))
}
}
> myfun(x)
[1] NA 8 7 NA 3 3 NA -1 4
> y <- c(x, NA, NA, NA, 3)
> y
[1] NA NA 8 7 NA NA NA NA NA 3 3 NA -1 4 NA NA NA 3
> myfun(y)
[1] NA 8 7 NA 3 3 NA -1 4 NA 3
> myfun(NA)
[1] NA
> myfun(1)
[1] 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With