Kat*_*e K 11 r time-series zoo xts
有没有办法我们可以NA用一个有限数量的前锋填充一个zoo或一个xts对象NA.换句话说,NA最多连续3次填充s NA,然后将NAs从第4个值保持到有效数字.
像这样的东西.
library(zoo)
x <- zoo(1:20, Sys.Date() + 1:20)
x[c(2:4, 6:10, 13:18)] <- NA
x
2014-09-20 2014-09-21 2014-09-22 2014-09-23 2014-09-24 2014-09-25 2014-09-26 
         1         NA         NA         NA          5         NA         NA 
2014-09-27 2014-09-28 2014-09-29 2014-09-30 2014-10-01 2014-10-02 2014-10-03 
        NA         NA         NA         11         12         NA         NA 
2014-10-04 2014-10-05 2014-10-06 2014-10-07 2014-10-08 2014-10-09 
        NA         NA         NA         NA         19         20
期望的输出,将是变量n = 3的东西
2014-09-20 2014-09-21 2014-09-22 2014-09-23 2014-09-24 2014-09-25 2014-09-26 
         1         1         1        1          5         5        5 
2014-09-27 2014-09-28 2014-09-29 2014-09-30 2014-10-01 2014-10-02 2014-10-03 
        5         NA         NA         11         12         12        12 
2014-10-04 2014-10-05 2014-10-06 2014-10-07 2014-10-08 2014-10-09 
        12         NA         NA         NA         19         20
我已经尝试了许多组合na.locf(x, maxgap = 3)等没有太大的成功.我可以创建一个循环来获得所需的输出,我想知道是否有矢量化的方法来实现这一点.
fillInTheBlanks <- function(v, n=3) {
  result <- v
  counter0 <- 1
  for(i in 2:length(v)) {
    value <- v[i]
    if (is.na(value)) {
      if (counter0 > n) {
        result[i] <- v[i]
      } else {  
        result[i] <- result[i-1]
        counter0 <- counter0 + 1
      } }   
    else {
      result[i] <- v[i] 
      counter0 <- 1
    }
  }
  return(result)
}
谢谢
Mat*_*rde 11
这是另一种方式:
l <- cumsum(! is.na(x))
c(NA, x[! is.na(x)])[replace(l, ave(l, l, FUN=seq_along) > 4, 0) + 1]
# [1]  1  1  1  1  5  5  5  5 NA NA 11 12 12 12 12 NA NA NA 19 20
编辑:我之前的答案要求x没有重复.目前的答案没有.
基准
x <- rep(x, length.out=1e4)
plourde <- function(x) {
    l <- cumsum(! is.na(x))
    c(NA, x[! is.na(x)])[replace(l, ave(l, l, FUN=seq_along) > 4, 0) + 1]
}
agstudy <- function(x) {
    unlist(sapply(split(coredata(x),cumsum(!is.na(x))),
           function(sx){
             if(length(sx)>3) 
               sx[2:4] <- rep(sx[1],3)
             else sx <- rep(sx[1],length(sx))
             sx
           }))
}
microbenchmark(plourde(x), agstudy(x))
# Unit: milliseconds
#        expr   min     lq median     uq   max neval
#  plourde(x)  5.30  5.591  6.409  6.774 57.13   100
#  agstudy(x) 16.04 16.249 16.454 17.516 20.64   100