将日历周转换为每日日期

时间:2016-01-28 20:07:02

标签: r calendar time-series

我得到了一个包含两列的列表,2015年的日历周和值:

calender week   Value
        KW 1    14000
        KW 2    24000

遗憾的是 - 我收到的文件中没有更多信息。但是,我需要分析的是每日时间序列,因此我需要将KW 1等转换为具有相应日期的列(注意:日历周始终以星期一开始!):

calender week   date        Value
      KW 1      29-12-13    2000
      KW 1      30-12-13    2000
      KW 1      31-12-13    2000
      KW 1      01-01-14    2000
      KW 1      02-01-14    2000
      KW 1      03-01-14    2000
      KW 1      04-01-14    2000
      KW 2      05-01-14    3000
      KW 2      06-01-14    3000
      KW 2      07-01-14    3000
      KW 2      08-01-14    3000
      KW 2      09-01-14    3000
      KW 2      10-01-14    3000
      KW 2      11-01-14    3000

该值仅为7(=一个日历周的天数)。

拜托,有人可以帮助我吗?

1 个答案:

答案 0 :(得分:1)

lubridate包可以帮到你。它提供了轻松操作日期的功能。

在您的示例中似乎年份不变,因此我假设所有日期都在2014年(或在2013年的最后几天,从第1周开始于12月30日)。如果您不熟悉lubridate,以下内容将包含许多您不知道的功能。使用?获取有关他们的帮助(例如?ymd)。

第一步是获得一年中第一周的星期一。当然,您可以查找它,但可以使用lubridate来计算它:

library(lubridate)
start_date <- ymd("20140201")
week(start_date) <- 1
wday(start_date) <- "Monday"
start_date
## [1] "2013-12-30 UTC"

首先选择2014年的任意一天,然后将周数设置为1,将工作日设置为周一。现在我可以通过添加适当的周数来获得任何日历周的第一天:

start_date + weeks(2)
## [1] "2014-01-13 UTC"

现在我创建一个三周的样本数据集:

data <- data.frame(week  = paste("KW", 1:3), value = c(14000, 21000,  28000))
data
##   week value
## 1 KW 1 14000
## 2 KW 2 21000
## 3 KW 3 28000

转换为所需格式的方式如下:

weeks <- rep(data$week, each = 7)
weeks_num = as.numeric(gsub("KW *", "", weeks))
intervals <- weeks(weeks_num - 1) + days(0:6)
dates <- as.Date(start_date + intervals)
values <- rep(data$value, each = 7)/7
new_data <- data.frame(week = weeks, date = dates, value = values)
new_data
##    week       date value
## 1  KW 1 2013-12-30  2000
## 2  KW 1 2013-12-31  2000
## 3  KW 1 2014-01-01  2000
## 4  KW 1 2014-01-02  2000
## 5  KW 1 2014-01-03  2000
## 6  KW 1 2014-01-04  2000
## 7  KW 1 2014-01-05  2000
## 8  KW 2 2014-01-06  3000
## 9  KW 2 2014-01-07  3000
## 10 KW 2 2014-01-08  3000
## 11 KW 2 2014-01-09  3000
## 12 KW 2 2014-01-10  3000
## 13 KW 2 2014-01-11  3000
## 14 KW 2 2014-01-12  3000
## 15 KW 3 2014-01-13  4000
## 16 KW 3 2014-01-14  4000
## 17 KW 3 2014-01-15  4000
## 18 KW 3 2014-01-16  4000
## 19 KW 3 2014-01-17  4000
## 20 KW 3 2014-01-18  4000
## 21 KW 3 2014-01-19  4000

其工作原理如下:

  • 首先我准备日期。每个日历周重复七次(每天一次)。然后删除“KW”部分并将周转换为数字。之后,我使用lubridate函数weeks()days()来构建自start_date以来所需的所有时间间隔。

  • 我计算了这些值。其中每一个也在一周中的每一天重复并除以七。

  • 最后,我将结果放入一个新的数据框中。

最后一句话:这是一个复杂的解决方案。如果您确定,没有任何一周会丢失,那么简单地生成一系列日期就更容易,甚至不考虑日历周的列,如下所示:

dates <- as.Date(start_date + days(0:(7*nrow(data) - 1)))
identical(new_data$date, dates)
## [1] TRUE

因此,我只需使用nrows()计算周数,然后生成days()的时间间隔序列,然后添加到start_date。 但是,如果缺少日历周,则应使用上面更一般的解决方案。