knitr::opts_chunk$set( collapse = TRUE, fig.width = 3.4, fig.height = 2.4, comment = "#>" )
library(dint)
dint helps you with working with year-quarter, year-month and year-isoweek
dates. It stores them in an easily human readable integer format, e.q 20141
for the first quarter of 2014 and so forth. If you are already using such
integers to represent dates, dint can make many common operations easier for
you.
dint is implemented in base R and comes with zero external dependencies. Even if you don't work with such special dates directly, dint can still help you at formatting dates, labelling plot axes, or getting first / last days of calendar periods (quarters, months, isoweeks).
dint provides 4 different S3 classes that inherit from date_xx
^[date_xx
is
just a superclass for all dint date classes, you do not need to use it directly].
date_yq
for year-quarter datesdate_yw
for year-month datesdate_yw
for year-isoweek dates. Please note that the year for isoweeks does
not necessarily correspond to the calendar year
wikipediadate_y
for storing years. This class exists for consistency and provides
little 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_xx
vectors can be created using explicit constructors...
date_yq(2015, 1) date_ym(c(2015, 2016), c(1, 2)) date_yw(c(2008, 2009), 1)
..or through coercion of Dates
or integers
as_date_yq(Sys.Date()) as_date_yq(20141) # the last digit is interpreted as quarter as_date_ym(201412) # the last two digits are interpreted as month as_date_yw("2018-01-01") # anything else that can be parsed by as.Date() works
You can coerce Dates
to any date_xx
subclass with as_date_**()
d <- as.Date("2018-05-12") as_date_yq(d) as_date_ym(d) as_date_yw(d) as_date_y(d)
Conversely, you can convert date_xx
back to R Dates
q <- date_yq(2015, 1) as.Date(q) as.POSIXlt(q)
as.POSIXct()
creates datetimes in UTC/GMT, so the result might not always be
as expected, depending on your local timezone.
as.POSIXct(q) as.POSIXct(q, tz = "GMT") print(as.POSIXct(q), tz = "GMT") print(as.POSIXct(q), tz = "CET")
All date_xx
support addition, subtraction and sequence generation.
q <- date_yq(2014, 4) q + 1 q - 1 seq(q - 2, q + 2) m <- date_ym(2014, 12) m + 1 m - 1 seq(m - 2, m + 2) w <- date_yw(2017, 33) w + 1 w - 1 seq(w - 2, w + 2)
You can access components of date_xx
(e.g the quarter of a date_yq
) with
accessor functions. You can also use these functions to convert between
date_xx
vectors.
q <- date_yq(2014, 4) get_year(q) get_quarter(q) get_month(q) # defaults to first month of quarter get_isoweek(q) m <- date_ym(2014, 12) get_year(m) get_quarter(m) get_month(m) get_isoweek(m) w <- date_yw(2014, 33) get_year(w) get_quarter(w) get_month(w) get_isoweek(w)
If you use lubridate, you can just use the slightly less verbose lubridate accessors
suppressPackageStartupMessages(library(lubridate)) year(q) quarter(q) month(q)
You can 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 last_of_quarter(q)
These functions work with normal dates
d <- as.Date("2018-05-12") first_of_year(d) last_of_year(d) first_of_quarter(d) last_of_quarter(d) first_of_month(d) last_of_month(d) first_of_isoweek(d) last_of_isoweek(d) # Alternativeley you can use these: first_of_yq(2012, 2) last_of_ym(2012, 2) last_of_yw(2011, 52)
Formatting date_xx
vectors 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 format(q, "%Y.%q") format(q, "%y.%q") m <- date_ym(2014, 12) format(m, "%Y-M%m") # iso/default w <- date_yw(2014, 1) format(w, "%Y-W%V") # iso/default
dint also provides all-in-one functions for common tasks
format_yq(Sys.Date()) format_yq_short(Sys.Date()) format_yq_shorter(Sys.Date()) format_ym(Sys.Date()) format_yw(Sys.Date())
library(ggplot2)
dint implements scale_date_**()
and date_**_breaks()
that provide nicely
labeled axes for ggplots by default
q <- data.frame( time = seq(date_yq(2016, 1), date_yq(2016, 4)), value = rnorm(4) ) m <- data.frame( time = seq(date_ym(2016, 8), date_ym(2016, 11)), value = rnorm(4) ) w <- data.frame( time = seq(date_yw(2016, 48), date_yw(2017, 1)), value = abs(rnorm(6)) ) w2 <- data.frame( time = seq(date_yw(2016, 1), date_yw(2019, 1)), value = abs(rnorm(157)) ) ggplot(q, aes(x = time, y = value)) + geom_point() ggplot(m, aes(x = time, y = value)) + geom_line() + scale_x_date_ym(labels = format_ym_shorter) ggplot(w, aes(x = time, y = value)) + geom_col() + scale_x_date_yw(labels = format_yw_iso) ggplot(w2, aes(x = time, y = value)) + geom_smooth()
If you use R Date
vectors, you can still use the formatting functions supplied
by dint to generate nice axis labels.
x <- data.frame( time = seq(as.Date("2016-01-01"), as.Date("2016-08-08"), by = "day"), value = rnorm(221) ) 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")
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.