【问题标题】:R: Filling timeseries values but only within last 12 monthsR:填充时间序列值,但仅在过去 12 个月内
【发布时间】:2018-05-26 04:16:40
【问题描述】:

我们如何在 R 中填充/转发时间序列,但前提是最后一个值在过去 12 个月/观察中,否则不适用?

样本数据:变量是原始数据,期望是期望的结果。 我们从 2016 年 6 月开始观察 NA,但我们将转发 pad。我只想这样做 12 个月,所以一旦我们到达 2017 年 7 月,最后一个非 NA 时间太长了,应该是 NA。这就是为什么像 fill() 这样的东西不会这样做的原因

example

最小工作示例:考虑以下使用 max gap 和 na.locf

x = c(NA,1,2,3,NA,NA,5,6,7,NA,NA,NA)
zoo::na.locf(x,  maxgap = 2, na.rm = FALSE)

当 NAs 的数量> 最大间隙时,我想要以下输出,而不是不填充任何内容: 不适用,1,2,3,3,3,5,6,7,7,7,不适用。因此,如果我指定 gap =2,我最多希望填充两个值,并且更多的 NA 应该保持 NA

【问题讨论】:

  • 填充/转发时间序列是什么意思?您能否添加一个您想要的结果的示例,以便我们提供更好的帮助?
  • 他可能在时间序列数据中缺少日期,并希望插入日期以创建统一的时间步长。但过去 12 个月是从哪一天开始的?
  • 数据已经有统一的时间步长。我想填写 NA,但如果最后一个可用值超过 12 个月前,请改为设置 NA
  • @Kathi 请添加一些示例数据,以便人们可以轻松地帮助您。您应该期望其他人花时间为您创建示例数据。请注意image 没有帮助,因为它需要有人打字。

标签: r time-series


【解决方案1】:

你可以这样做:

my_fill <- function(x,maxgap=2){
  y<-x
  counter<-0
  for(i in 2:length(y)){
    if(is.na(y[i] & counter<maxgap)){
      y[i]<-y[i-1]
      counter<-counter+1
    }else{
      counter<-0
    }
  }
  return(y)
}

x = c(NA,1,2,3,NA,NA,5,6,7,NA,NA,NA)
my_fill(x)

【讨论】:

    【解决方案2】:

    这是使用基数 R 的单线。k 指定间隙大小。 x 在问题的最小工作示例中定义。

    cumsum(!is.na(x)) 产生一个分组向量,其中每个非 NA 后跟任何 NA 被视为一个组。然后对于每个这样的组,用该组的第一个元素替换前 k+1 个元素(或组中元素的数量,如果更少),其余元素为 NA。

    k <- 2
    ave(x, cumsum(!is.na(x)), FUN = function(x) replace(x, 1:min(length(x), k+1), x[1]))
    ## [1] NA  1  2  3  3  3  5  6  7  7  7 NA
    

    请注意,这个想法也用于这个 SO 答案Change maxgap for number of times a value is carried forward 涉及 data.table。

    【讨论】:

      【解决方案3】:

      一个选项是使用tidyr::fill。该方法是将列创建为desiredTempDate,这样desired 将具有与variable 相同的值,但具有variable""(空白)值的行将具有desired 作为NA。同样,TempDate 将具有与 date 相同的值,但对于 variable 获得 "" 值的行,它将具有 NA

      fill desiredTempDate 并将 desired 替换为 NA,其中 TempDatedate 大 12 个月以上。

      library(tidyverse)
      library(lubridate)
      
      df %>% mutate(TempDate = as.Date(ifelse(variable=="", NA, date),origin = "1970-01-01"),
                    desired = ifelse(variable=="",NA, variable)) %>%
        fill(desired, TempDate) %>%
        mutate(desired = ifelse(date > (TempDate +months(12)), NA, desired)) %>%
        select(-TempDate)
      
      #          date variable desired
      # 1  2016-01-01        1       1
      # 2  2016-02-01        2       2
      # 3  2016-03-01        3       3
      # 4  2016-04-01        3       3
      # 5  2016-05-01        3       3
      # 6  2016-06-01       33      33
      # 7  2016-07-01               33
      # 8  2016-08-01               33
      # 9  2016-09-01               33
      # 10 2016-10-01               33
      # 11 2016-11-01               33
      # 12 2016-12-01               33
      # 13 2017-01-01               33
      # 14 2017-02-01               33
      # 15 2017-03-01               33
      # 16 2017-04-01               33
      # 17 2017-05-01               33
      # 18 2017-06-01               33
      # 19 2017-07-01             <NA>
      # 20 2017-08-01             <NA>
      # 21 2017-09-01       34      34
      # 22 2017-10-01               34
      

      数据:基于 OP 分享的图片

      df <- data.frame(date = seq(as.Date("2016-01-01"), as.Date("2017-10-01"), by="month"),
                 variable = c(1,2,3,3,3,33,rep("",14),34,""), stringsAsFactors = FALSE)
      
      df
      #          date variable
      # 1  2016-01-01        1
      # 2  2016-02-01        2
      # 3  2016-03-01        3
      # 4  2016-04-01        3
      # 5  2016-05-01        3
      # 6  2016-06-01       33
      # 7  2016-07-01         
      # 8  2016-08-01         
      # 9  2016-09-01         
      # 10 2016-10-01         
      # 11 2016-11-01         
      # 12 2016-12-01         
      # 13 2017-01-01         
      # 14 2017-02-01         
      # 15 2017-03-01         
      # 16 2017-04-01         
      # 17 2017-05-01         
      # 18 2017-06-01         
      # 19 2017-07-01         
      # 20 2017-08-01         
      # 21 2017-09-01       34
      # 22 2017-10-01         
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-08
        • 1970-01-01
        • 2019-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-03
        • 1970-01-01
        相关资源
        最近更新 更多