+ - 0:00:00
Notes for current slide
Notes for next slide

Module 8-1 Demonstration

Special Operations: Dealing with date/time

1 / 24

Date-time Basics

  • Base R has functions to get the current date and time.

  • Also the lubridate package offers fast and user friendly parsing of date-time data.

# get date information
Sys.Date()
## [1] "2024-05-01"
# get current time
Sys.time()
## [1] "2024-05-01 12:42:12 AEST"
install.packages("lubridate")
library(lubridate)
# get current time using `lubridate`
now()
## [1] "2024-05-01 12:42:13 AEST"
2 / 24

Date-time manipulations

  • When date and time data are imported into R they will often default to:

    • a factor or character due to symbols such as -, : and /
candy <- read.csv("../data/candy_production.csv")
head(candy,3)
## observation_date IPG3113N
## 1 1972-01-01 85.6945
## 2 1972-02-01 71.8200
## 3 1972-03-01 66.0229
class(candy$observation_date)
## [1] "character"
candy <- read.csv("../data/candy_production.csv", stringsAsFactors = FALSE)
head(candy,3)
## observation_date IPG3113N
## 1 1972-01-01 85.6945
## 2 1972-02-01 71.8200
## 3 1972-03-01 66.0229
class(candy$observation_date)
## [1] "character"
3 / 24

Date-time manipulations Cont.

  • Or sometimes they are converted into a numeric (integer) format:
library(lubridate)
head(lakers,3)
## date opponent game_type time period etype team player
## 1 20081028 POR home 12:00 1 jump ball OFF
## 2 20081028 POR home 11:39 1 shot LAL Pau Gasol
## 3 20081028 POR home 11:37 1 rebound LAL Vladimir Radmanovic
## result points type x y
## 1 0 NA NA
## 2 missed 0 hook 23 13
## 3 0 off NA NA
class(lakers$date)
## [1] "integer"
4 / 24

Date-time manipulations Cont.

  • If this is the case, we need to convert these to proper date format.
  • We can use different strategies to convert them to a date format:

    • as.Date() function under Base R.
    • lubridate package functions
5 / 24

Example 1: Convert factors to date with as.Date()

candy <- read.csv("../data/candy_production.csv")
head(candy,3)
## observation_date IPG3113N
## 1 1972-01-01 85.6945
## 2 1972-02-01 71.8200
## 3 1972-03-01 66.0229
class(candy$observation_date)
## [1] "character"
candy_date <- as.Date(candy$observation_date)
class(candy_date)
## [1] "Date"
6 / 24

Example 2: Convert strings to date with as.Date()

candy <- read.csv("../data/candy_production.csv", stringsAsFactors = FALSE)
head(candy,3)
## observation_date IPG3113N
## 1 1972-01-01 85.6945
## 2 1972-02-01 71.8200
## 3 1972-03-01 66.0229
class(candy$observation_date)
## [1] "character"
candy_date <- as.Date(candy$observation_date)
class(candy_date)
## [1] "Date"
7 / 24

Date-time manipulations Cont.

  • Note that the default date format is YYYY-MM-DD; therefore, if your string is of different format you must incorporate the format argument.

  • Have a look at these two examples:

x <- c("08/03/2018", "23/03/2016", "30/01/2018")
y <- c("08.03.2018", "23.03.2016", "30.01.2018")
  • This time the string format is DD/MM/YYYY for x and DD.MM.YYYY for y; therefore, we need to specify the format argument explicitly.
x_date <- as.Date(x, format = "%d/%m/%Y")
y_date <- as.Date(y, format = "%d.%m.%Y")
  • For format specifications type ?strftime in your console.
8 / 24

Date-time manipulations with lubridate

  • The lubridate package can automatically recognise the common separators used when recording dates (-, /, ., and ).
  • As a result, you only need to focus on specifying the order of the date elements. For example:
a <- c("26/03/2016", "08/12/2011", "05/01/2013")
  • In order to convert a into a date, we can use dmy() (Day, Month, Year)
library(lubridate)
a_date <- dmy(a)
a_date
## [1] "2016-03-26" "2011-12-08" "2013-01-05"
9 / 24

Date-time manipulations with lubridate

  • Here is the list of lubridate functions used for this purpose:
Function Order of elements in date-time
ymd() year, month, day
ydm() year, day, month
mdy() month, day, year
dmy() day, month, year
hm() hour, minute
hms() hour, minute, second
ymd_hms() year, month, day, hour, minute, second
10 / 24

Your turn! Activity

  • Convert the following strings into a date format first using as.Date() and then lubridate functions.
task1 <- c("08032018", "29062017", "23032016", "30012018")
task2 <- c("08}03}2018", "29}06}2017", "23}03}2016", "30}01}2018")
task3 <- c("08.03.2018", "29062017", "23/03/2016", "30-01-2018")
11 / 24
task1 <- c("08032018", "29062017", "23032016", "30012018")
# using as.Date
date_task1 <- as.Date(task1, format = "%d%m%Y")
class(date_task1)
## [1] "Date"
# using lubridate
date_task1 <- dmy(task1)
class(date_task1)
## [1] "Date"
task2 <- c("08}03}2018", "29}06}2017", "23}03}2016", "30}01}2018")
# using as.Date
date_task2 <- as.Date(task2, format = "%d}%m}%Y")
class(date_task2)
## [1] "Date"
# using lubridate
date_task2 <- dmy(task2)
class(date_task2)
## [1] "Date"
task3 <- c("08.03.2018", "29062017", "23/03/2016", "30-01-2018")
# using as.Date
date_task3 <- as.Date(task3, format = c("%d.%m.%Y", "%d%m%Y", "%d/%m/%Y", "%d-%m-%Y"))
date_task3
## [1] "2018-03-08" "2017-06-29" "2016-03-23" "2018-01-30"
class(date_task3)
## [1] "Date"
# using lubridate
date_task3 <- dmy(task3)
class(date_task3)
## [1] "Date"
  • As seen, lubridate is very flexible in recognising separators.

Extract & manipulate parts of dates

  • Sometimes, instead of a single string, we will have date-time spread across multiple columns.

  • Remember the flights data in the nycflights13 package.

library(nycflights13)
head(flights[,c(1:3, 17:18)])
## # A tibble: 6 × 5
## year month day hour minute
## <int> <int> <int> <dbl> <dbl>
## 1 2013 1 1 5 15
## 2 2013 1 1 5 29
## 3 2013 1 1 5 40
## 4 2013 1 1 5 45
## 5 2013 1 1 6 0
## 6 2013 1 1 5 58
  • As seen, the components of the date information is given in multiple columns.
12 / 24

Extract & manipulate parts of dates Cont.

  • To create a date/time from this sort of input, we can use make_date() for dates and make_datetime() for date-times.
## # A tibble: 6 × 5
## year month day hour minute
## <int> <int> <int> <dbl> <dbl>
## 1 2013 1 1 5 15
## 2 2013 1 1 5 29
## 3 2013 1 1 5 40
## 4 2013 1 1 5 45
## 5 2013 1 1 6 0
## 6 2013 1 1 5 58
flights_new<- flights %>% mutate(departure = make_datetime(year, month, day, hour, minute))
head(flights_new$departure)
## [1] "2013-01-01 05:15:00 UTC" "2013-01-01 05:29:00 UTC"
## [3] "2013-01-01 05:40:00 UTC" "2013-01-01 05:45:00 UTC"
## [5] "2013-01-01 06:00:00 UTC" "2013-01-01 05:58:00 UTC"
13 / 24

Extract & manipulate parts of dates Cont.

  • Conversely, we can extract individual parts of the date with the accessor functions in lubridate. Here is the list of available functions:
Accessor Function Extracts
year() year
month() month
mday() day of the month
yday() day of the year
wday() day of the week
hour() hour
minute() minute
second() second
14 / 24

Extract & manipulate parts of dates Cont.

  • For example to extract the year information of the flights_new$departure column we can use:
flights_new$departure %>% year() %>% head()
## [1] 2013 2013 2013 2013 2013 2013
  • We can also use accessor functions to change the components of a date/time:
# create a date
datetime <- ymd_hms("2016-07-08 12:34:56")
# replace the year component with 2020
year(datetime) <- 2020
# replace the month component with January
month(datetime) <- 01
datetime
## [1] "2020-01-08 12:34:56 UTC"
15 / 24

Date arithmetic

  • Often we may require to compute a new variable from the date - time information.

  • In order to calculate time difference, simply subtract two dates:

my_age <- today() - ymd(19810529)
my_age
## Time difference of 15678 days
  • Or use difftime() function
my_age <- difftime(today(), ymd(19810529))
my_age
## Time difference of 15678 days
  • As a result, we'll get a time intervals/differences object (a.k.a difftime in R)
16 / 24

Date arithmetic Cont.

  • To change the time difference to another unit we can use units argument:
my_age_secs<-difftime(today(), ymd(19810529), units = "secs")
my_age_secs
## Time difference of 1354579200 secs
  • units can be "auto", "secs", "mins", "hours", "days", "weeks".

  • Note that difftime objects do not accept 'years' as a value for 'units'.

  • To get my age in years:

my_age_days<-difftime(today(), ymd(19810529), units = "days")
my_age_years<- as.numeric(my_age_days/365.25)
my_age_years
## [1] 42.92402
17 / 24

Date arithmetic Cont.

  • A sequence of dates/times can be created using seq() function with specifying four arguments seq(from, to, by, length.out).
# create a sequence of years from 1980 to 2018 by 2
even_years <- seq(from = 1980, to=2018, by = 2)
even_years
## [1] 1980 1982 1984 1986 1988 1990 1992 1994 1996 1998 2000 2002 2004 2006 2008
## [16] 2010 2012 2014 2016 2018
# create a sequence of hours from 1/1/2018 9:00 to 1/1/2018 12:00
hour_list <- seq (ymd_hm("2018-1-1 9:00"), ymd_hm("2018-1-1 12:00"), by = "hour")
hour_list
## [1] "2018-01-01 09:00:00 UTC" "2018-01-01 10:00:00 UTC"
## [3] "2018-01-01 11:00:00 UTC" "2018-01-01 12:00:00 UTC"
18 / 24

Date arithmetic: durations

  • A difftime class object records a time span of seconds, minutes, hours, days, or weeks.
  • lubridate provides an alternative which always uses seconds: the duration.
Duration Function Usage
as.duration() assigns duration in seconds
is.duration() check if it is duration
dseconds duration in seconds
dminutes duration in minutes
dhours duration in hours
ddays duration in days
dweeks duration in years
dyears duration in years
  • Minutes = 60 secs, hours = 3600 secs, days = 86400 secs, weeks = 604800 secs.
as.duration(my_age_secs)
## [1] "1354579200s (~42.92 years)"
19 / 24

Date arithmetic: durations Cont.

  • With durations, date arithmetics would become easier:
# three weeks later
today() + dweeks(3)
## [1] "2024-05-22"
# tomorrow
today() + ddays(1)
## [1] "2024-05-02"
# last year
today() - dyears(1)
## [1] "2023-05-01 18:00:00 UTC"
20 / 24

Date arithmetic: durations Cont.

# two years, 12 weeks and 15 hours before
today() - ( dyears(2) + dweeks(12) + dhours(15) )
## [1] "2022-02-05 21:00:00 UTC"
#same as above:
today() - ( 2*dyears(1) + dweeks(12) + dhours(15) )
## [1] "2022-02-05 21:00:00 UTC"
21 / 24

Your turn! Activity

  • Task 1: Set up 10 weekly skype meeting with your manager (start it from today)
  • Task 2: Find the weekday (i.e. Monday, Tuesday, Wednesday etc) of the day when you were born.
22 / 24
task1 <- today() + dweeks(0:9)
task1
## [1] "2024-05-01" "2024-05-08" "2024-05-15" "2024-05-22" "2024-05-29"
## [6] "2024-06-05" "2024-06-12" "2024-06-19" "2024-06-26" "2024-07-03"
task2 <- wday( dmy(29051981), label = T)
task2
## [1] Fri
## Levels: Sun < Mon < Tue < Wed < Thu < Fri < Sat

Functions to Remember for Week 10

  • Date/time manipulations using BaseR and lubridate

    • as.Date(), ymd(), ydm(), mdy()...etc.
    • year(), month(), mday(), yday(), wday(), ...etc.
    • duration functions: duration(), dminutes() , dhours(), ..etc
  • Practice!

23 / 24

Your turn! Class Worksheet

  • Working in small groups, complete the following class worksheet

Module 8-1 Worksheet

  • Once completed, feel free to work on your Assessments.


Return to Course Website

24 / 24

Date-time Basics

  • Base R has functions to get the current date and time.

  • Also the lubridate package offers fast and user friendly parsing of date-time data.

# get date information
Sys.Date()
## [1] "2024-05-01"
# get current time
Sys.time()
## [1] "2024-05-01 12:42:12 AEST"
install.packages("lubridate")
library(lubridate)
# get current time using `lubridate`
now()
## [1] "2024-05-01 12:42:13 AEST"
2 / 24
Paused

Help

Keyboard shortcuts

, , Pg Up, k Go to previous slide
, , Pg Dn, Space, j Go to next slide
Home Go to first slide
End Go to last slide
Number + Return Go to specific slide
b / m / f Toggle blackout / mirrored / fullscreen mode
c Clone slideshow
p Toggle presenter mode
t Restart the presentation timer
?, h Toggle this help
Esc Back to slideshow