我需要将矢量中的连续NA减少到单个NA,而不接触其他值 所以,例如,给出这样的矢量:
NA NA 8 7 NA NA NA NA NA 3 3 NA -1 4
我需要得到的是以下结果:
NA 8 7 NA 3 3 NA -1 4
目前,我正在使用以下功能:
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)])
}
它似乎工作正常,但可能有一种更简单/更快的方法来完成这项任务。
有什么建议吗?
提前致谢。
答案 0 :(得分:13)
这是一个想法:
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
答案 1 :(得分:3)
也许这可能有用
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
如果你想要一个功能试试:
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
答案 2 :(得分:3)
使用head
和tail
进行有趣的小练习:
merge.na <- function(x) c(head(x, 1), tail(x, -1)[!(is.na(tail(x, -1)) &
is.na(head(x, -1)))])
答案 3 :(得分:0)
不像其他回复那么酷,而是使用rle
的不同方法:
x <- c(NA, NA, 8, 7, NA, NA, NA, NA, NA, 3, 3, NA, -1, 4)
x[is.na(x)] <- 999
y <- rle(x)
y[[1]][y[[2]]==999] <- 1
y[[2]][y[[2]]==999] <- NA
rep(y[[2]], y[[1]])
#per Dason's Suggestion:
inverse.rle(y)
实际上,rle
并未将NA分组在一起,这实在令人惊讶。它这样做:
> rle(x)
Run Length Encoding
lengths: int [1:13] 1 1 1 1 1 1 1 1 1 2 ...
values : num [1:13] NA NA 8 7 NA NA NA NA NA 3 ...
因此需要重新编码为999