How can I create dates in Year/Semester format in R?

余生颓废 提交于 2019-12-06 00:36:01

Sir, I suggest you to use lubridate package, to deal with custom date intervals. Your task could be easy accomplished applying floor_date, as below:

six_m_interval <- lubridate::floor_date( dt , "6 months" )
# [1] "2001-01-01" "2001-01-01" "2001-01-01" "2001-01-01" "2001-07-01" "2001-07-01"

aggregate( daily_db , six_m_interval , sum )
#                  V1          V2         V3
# 2001-01-01  3.538950  1.17559873 -2.1478445
# 2001-07-01 -1.125309 -0.03541579 -0.6396977

Date2period

Date2period inputs a "Date" object and returns a character string representing a period (semester, etc.) depending on the value of argument period which should be a number that is a divisor of 12. Internally it converts to yearmon and then extracts the year and cycle, i.e. month, and from those generates the required string.

Date2period <- function(x, period = 6, sep = " S") {
  ym <- as.yearmon(x)
  paste(as.integer(ym), (cycle(ym) - 1) %/% period + 1, sep = sep)
}

To test the above:

library(zoo)

# inputs
period <- 6
dt <- as.Date(c("2001-01-01","2001-04-01","2001-07-01","2001-10-01"))

Date2period(dt)
## [1] "2001 S1" "2001 S1" "2001 S2" "2001 S2"

aggregate(daily_db, Date2period, sum)
##                V1        V2          V3
## 2001 S1 0.9367209 -1.125309  2.39888622
## 2001 S2 2.6022286 -1.223287 -0.03541579

period2yearmon, period2Date

Here are additional conversion functions but for the other direction:

period2yearmon <- function(x, period = 6) {
     year <- as.numeric(sub("\\D.*", "", x))
     cyc <- as.numeric(sub(".*\\D", "", x))
     as.yearmon(year + period * (cyc - 1) / 12)
}

period2Date <- function(x, period = 6) as.Date(period2yearmon(x, period))

Here are some tests of these functions. Since converting from Date to period and back to Date gives the date at the beginning of the period that the input date lies in we show the effect in aggregate at the end.

# create a period string
d <- Date2period(dt)
## [1] "2001 S1" "2001 S1" "2001 S2" "2001 S2"

period2yearmon(d)
## [1] "Jan 2001" "Jan 2001" "Jul 2001" "Jul 2001"

period2Date(d)
## [1] "2001-01-01" "2001-01-01" "2001-07-01" "2001-07-01"

aggregate(daily_db, function(x) period2Date(Date2period(x)), sum)
##                   V1        V2          V3
## 2001-01-01 0.9367209 -1.125309  2.39888622
## 2001-07-01 2.6022286 -1.223287 -0.03541579

This could be made more sophisticated by creating S3 objects such as yearmon but for the purposes shown in the question that is not really needed.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!