Dates and Times: lubridate
Prerequisites: Data types, dplyr: mutate, summarise, and group_by
Dates are stored as special types in R: Date for calendar days and
POSIXct for date-times. The lubridate package makes them easy to
parse and work with.
Parsing
lubridate's parsing functions are named after the order of the parts
in your data — y, m, d (and h, m, s for times):
library(lubridate, warn.conflicts = FALSE)
ymd("2025-01-15")
dmy("15/01/2025")
mdy("January 15, 2025")
ymd_hms("2025-01-15 09:30:00", tz = "UTC")
class(ymd("2025-01-15"))
[1] "2025-01-15"
[1] "2025-01-15"
[1] "2025-01-15"
[1] "2025-01-15 09:30:00 UTC"
[1] "Date"
All three formats became the same Date. Parsing dates stored as text is
one of the first cleaning steps for most datasets.
Extracting parts and doing arithmetic
library(lubridate, warn.conflicts = FALSE)
d <- ymd("2025-01-31")
year(d)
month(d, label = TRUE)
wday(d, label = TRUE)
d + days(30)
d %m+% months(1)
as.numeric(ymd("2025-12-25") - d)
floor_date(ymd("2025-03-17"), "month")
[1] 2025
[1] Jan
12 Levels: Jan < Feb < Mar < Apr < May < Jun < Jul < Aug < Sep < ... < Dec
[1] Fri
Levels: Sun < Mon < Tue < Wed < Thu < Fri < Sat
[1] "2025-03-02"
[1] "2025-02-28"
[1] 328
[1] "2025-03-01"
month(d, label = TRUE)returns an ordered factor, so charts show months in calendar order, not alphabetically.%m+% months(1)adds a calendar month, rolling back to the last valid day — 31 January becomes 28 February.floor_date(x, "month")rounds down to the start of the month — the standard way to group data by month.
Monthly totals
library(dplyr, warn.conflicts = FALSE)
library(lubridate, warn.conflicts = FALSE)
sales <- tibble(
date = ymd(c("2025-01-05", "2025-01-20", "2025-02-03")),
amount = c(100, 250, 80)
)
sales |>
mutate(month = floor_date(date, "month")) |>
summarise(total = sum(amount), .by = month)
# A tibble: 2 × 2
month total
<date> <dbl>
1 2025-01-01 350
2 2025-02-01 80
Common mistakes
- Ambiguous formats:
01/02/2025is 1 February in most of the world and 2 January in the US. Know your data's convention and usedmyormdyaccordingly. - Ignoring time zones for date-times. Store them in UTC, and set
tzexplicitly when parsing.