library(dint)
dint helps you with working with year-quarter and year-month dates. It is implemented in base R and comes with zero external dependencies. Even if you don’t need to work with such special dates directly, dint can still help you format (for example) plot axis.
dint provides 4 different S3 classes that inherit from date_xx
. * date_yq
for year-quarter dates * date_yw
for year-month dates * date_yw
for year-isoweek dates. Please note that the year for isoweeks does not necessarily correspond to the calender year wikipedia * date_y
for storing years. This class exists for consistency and provides litle advantage over storing years as bare integers. The main use of this class is in package development when you want to write your own generics and methods for years.
# date_* Objects can be created using explicit constructors...
date_yq(2015, 1)
#> [1] "2015-Q1"
date_ym(c(2015, 2016), c(1, 2))
#> [1] "2015-M01" "2016-M02"
date_yw(c(2008, 2009), 1)
#> [1] "2008-W01" "2009-W01"
# ...or through coercion of dates or integers
as_date_yq(Sys.Date())
#> [1] "2018-Q3"
as_date_yq(20141) # the last digit is interpreted as quarter
#> [1] "2014-Q1"
as_date_ym(201412) # the last two digits are interpreted as month
#> [1] "2014-M12"
as_date_yw("2018-01-01") # anything else that can be parsed by as.Date() works
#> [1] "2018-W01"
# You can coerce dates to any date_xx object with as_date_**
d <- as.Date("2018-05-12")
as_date_yq(d)
#> [1] "2018-Q2"
as_date_ym(d)
#> [1] "2018-M05"
as_date_yw(d)
#> [1] "2018-W19"
as_date_y(d)
#> [1] "2018"
# Conversely, you can convert date_xx objects back to the various R Date formats
q <- date_yq(2015, 1)
as.Date(q)
#> [1] "2015-01-01"
as.POSIXlt(q)
#> [1] "2015-01-01 UTC"
# as.POSIXct creates datetimes in UTC/GMT, so the result might not always be as
# expected, depending on your local timezone.
as.POSIXct(q)
#> [1] "2015-01-01 01:00:00 CET"
as.POSIXct(q, tz = "GMT")
#> [1] "2015-01-01 01:00:00 CET"
print(as.POSIXct(q), tz = "GMT")
#> [1] "2015-01-01 GMT"
print(as.POSIXct(q), tz = "CET")
#> [1] "2015-01-01 01:00:00 CET"
# Quarters
q <- date_yq(2014, 4)
q
#> [1] "2014-Q4"
q + 1
#> [1] "2015-Q1"
seq(q -2, q + 2)
#> [1] "2014-Q2" "2014-Q3" "2014-Q4" "2015-Q1" "2015-Q2"
# Months
m <- date_ym(2014, 12)
m
#> [1] "2014-M12"
m + 1
#> [1] "2015-M01"
seq(m -2, m + 2)
#> [1] "2014-M10" "2014-M11" "2014-M12" "2015-M01" "2015-M02"
q <- date_yq(2014, 4)
get_year(q)
#> [1] 2014
get_quarter(q)
#> [1] 4
get_month(q) # defaults to first month of quarter
#> [1] 10
m <- date_ym(2014, 12)
get_year(m)
#> [1] 2014
get_quarter(m)
#> [1] 4
get_month(m)
#> [1] 12
If you use lubridate, you can just use the slighly less verbose lubridate accessors
stopifnot(requireNamespace("lubridate"))
lubridate::year(q)
#> [1] 2014
lubridate::quarter(q)
#> [1] 4
lubridate::month(q)
#> [1] 10
You can also get the first and last days of calendar periods with dint
q <- date_yq(2015, 1)
first_of_quarter(q) # the same as as.Date(q), but more explicit
#> [1] "2015-01-01"
last_of_quarter(q) # the same as as.Date(q), but more explicit
#> [1] "2015-03-31"
# These functions work with normal dates
d <- as.Date("2018-05-12")
first_of_year(d)
#> [1] "2018-01-01"
last_of_year(d)
#> [1] "2018-12-31"
first_of_quarter(d)
#> [1] "2018-04-01"
last_of_quarter(d)
#> [1] "2018-06-30"
first_of_month(d)
#> [1] "2018-05-01"
last_of_month(d)
#> [1] "2018-05-31"
first_of_isoweek(d)
#> [1] "2018-05-07"
last_of_isoweek(d)
#> [1] "2018-05-13"
# Alternativeley you can also use these:
first_of_yq(2012, 2)
#> [1] "2012-04-01"
last_of_ym(2012, 2)
#> [1] "2012-02-29"
Formating date_yq
objects is easy and uses a subset of the placeholders of base::strptime()
(+ %q
for quarters).
q <- date_yq(2014, 4)
format(q, "%Y-Q%q") # iso/default
#> [1] "2014-Q4"
format(q, "%Y.%q")
#> [1] "2014.4"
format(q, "%y.%q")
#> [1] "14.4"
m <- date_ym(2014, 12)
format(m, "%Y-M%m") # iso/default
#> [1] "2014-M12"
w <- date_yw(2014, 1)
format(w, "%Y-W%W") # iso/default
#> [1] "2014-W01"
# You can use these for coercion and formatting in one step
format_yq(Sys.Date())
#> [1] "2018-Q3"
format_ym(Sys.Date())
#> [1] "2018-M09"
format_yw(Sys.Date())
#> [1] "2018-W39"
For convenience, dint provides direct formatting functions for dates that are useful for labelling ggplot axis.
library(ggplot2)
x <- data.frame(
time = seq(as.Date("2016-01-01"), as.Date("2016-08-08"), by = "day")
)
x$value <- rnorm(nrow(x))
p <- ggplot(
x,
aes(
x = time,
y = value)
) + geom_point()
p + ggtitle("iso") + ggtitle("default")
p + scale_x_date(labels = format_yq_iso) + ggtitle("date_yq_iso")
p + scale_x_date(labels = format_ym_short) + ggtitle("date_ym_short")
p + scale_x_date(labels = format_yw_shorter) + ggtitle("date_yw_shorter")