【问题标题】:Fill in missing year in ordered list of dates在有序日期列表中填写缺失的年份
【发布时间】:2014-10-27 06:22:13
【问题描述】:

我从网上收集了一些时间序列数据,我得到的时间戳如下所示。

24 Jun 
21 Mar
20 Jan 
10 Dec
20 Jun 
20 Jan
10 Dec 
...

有趣的是,数据中缺少年份,但是,所有记录都是有序的,您可以从记录中推断年份并填写缺失的数据。所以插补后的数据应该是这样的:

24 Jun 2014
21 Mar 2014
20 Jan 2014
10 Dec 2013 
20 Jun 2013
20 Jan 2013
10 Dec 2012
...

在举起袖子开始使用nested 逻辑编写for 循环之前.. 有没有一种简单的方法可以在R 中开箱即用来估算缺失的年份。

非常感谢您的任何建议!

【问题讨论】:

    标签: r date date-arithmetic


    【解决方案1】:

    OP 已要求从 2014 年开始按降序顺序完成年份。

    这是一种替代方法,它无需日期转换和假日期即可工作。此外,这种方法可以修改为适用于与一月不同月份开始的会计年度。

    # create sample dataset
    df <- data.frame(
      day = c(24L, 21L, 20L, 10L, 20L, 20L, 21L, 10L, 30L, 10L, 10L, 7L),
      month = c("Jun", "Mar", "Jan", "Dec", "Jun", "Jan", "Jan", "Dec", "Jan", 
                "Jan", "Jan", "Jun"))
    
    df$year <- 2014 - cumsum(c(0L, diff(100L*as.integer(
      factor(df$month, levels = month.abb)) + df$day) > 0))
    df
    
       day month year
    1   24   Jun 2014
    2   21   Mar 2014
    3   20   Jan 2014
    4   10   Dec 2013
    5   20   Jun 2013
    6   20   Jan 2013
    7   21   Jan 2012
    8   10   Dec 2011
    9   30   Jan 2011
    10  10   Jan 2011
    11  10   Jan 2011
    12   7   Jun 2010
    

    财政年度的完成

    假设公司决定在 2 月 1 日开始其会计年度。因此,1 月的会计年度与同一日历年的 2 月或 3 月不同。

    要处理会计年度,我们只需要相应地调整因子水平:

    df$fy <- 2014 - cumsum(c(0L, diff(100L*as.integer(
      factor(df$month, levels = month.abb[c(2:12, 1)])) + df$day) > 0))
    df
    
       day month year   fy
    1   24   Jun 2014 2014
    2   21   Mar 2014 2014
    3   20   Jan 2014 2013
    4   10   Dec 2013 2013
    5   20   Jun 2013 2013
    6   20   Jan 2013 2012
    7   21   Jan 2012 2011
    8   10   Dec 2011 2011
    9   30   Jan 2011 2010
    10  10   Jan 2011 2010
    11  10   Jan 2011 2010
    12   7   Jun 2010 2010
    

    【讨论】:

      【解决方案2】:

      这里有一个想法

      ## Make data easily reproducible
      df <- data.frame(day=c(24, 21, 20, 10, 20, 20, 10),
                       month = c("Jun", "Mar", "Jan", "Dec", "Jun", "Jan", "Dec"))
      
      
      ## Convert each month-day combo to its corresponding "julian date"
      datestring <- paste("2012", match(df[[2]], month.abb), df[[1]], sep = "-")
      date <- strptime(datestring, format = "%Y-%m-%d") 
      julian <- as.integer(strftime(date, format = "%j"))
      
      ## Transitions between years occur wherever julian date increases between
      ## two observations
      df$year <- 2014 - cumsum(diff(c(julian[1], julian))>0)
      
      ## Check that it worked
      df
      #   day month year
      # 1  24   Jun 2014
      # 2  21   Mar 2014
      # 3  20   Jan 2014
      # 4  10   Dec 2013
      # 5  20   Jun 2013
      # 6  20   Jan 2013
      # 7  10   Dec 2012
      

      【讨论】:

      • 如果一天内没有重复记录...也许可以将cumsum(diff(c(julian[1], julian))&gt;0)更改为大于或等于零。无论如何,非常感谢您的帮助。
      • 您可以跳过datestringdate 步骤,直接转到julianjulian &lt;- julian(ISOdate(2012, match(df[[2]], month.abb), df[[1]]))。其他一切都应该一样。
      • @MrFlick -- 谢谢你的建议。
      猜你喜欢
      • 2018-05-21
      • 2020-07-13
      • 2018-06-24
      • 2018-10-05
      • 2019-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多