r - 仅将时间序列中的 NA 填充到有限数量

标签 r time-series xts zoo

有什么办法可以填NA s 在 zooxts数量有限的对象 NA向前。换句话说,就像填充 NA s 最多连续 3 NA s,然后保留 NA s 从第 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)
}

谢谢

最佳答案

这是另一种方式:

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

关于r - 仅将时间序列中的 NA 填充到有限数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25940241/

相关文章:

r - Post查询后提取结果

r - zoo/xts 微秒读取问题

r - apply.monthly 给出该月最后一次观察的日期,而不是该月的最后一天

r - 使用端点函数来获取起点?

r - full_join 0 行数据

从 R 数据框中的某个位置滚动求和

R - 如何在交替列表元素的同时绑定(bind)两个列表

返回分组数据帧 R 中最大值的对应变量

R:使用 ggplot2 绘制带有分位数的时间序列

r - 如何使用 tsibble 和 fable 指定服务时间的间隔或频率?