Dates and Times with Lubridate

Prerequisites

library(tidyverse)
library(lubridate)
library(nycflights13)

Creating date/times

The three types of date/time data that refer to an instant in time:
  • Date. Tibbles print this as <date>
  • time within a day. Tibbles print this as <time>
  • date-time is a date plus a time: it uniquely identifies an instant in time. to the nearest second. Tibbles print this as <dttm>

    R doesn’t have a native class for storing times. If you need one, you se the hms package

    To get the date or date-time you can use today() or now()

    library(lubridate)
    
    Attaching package: <U+393C><U+3E31>lubridate<U+393C><U+3E32>
    
    The following object is masked from <U+393C><U+3E31>package:base<U+393C><U+3E32>:
    
        date
    today()
    [1] "2017-04-20"
    now()
    [1] "2017-04-20 14:21:40 MYT"
    The three ways to create a date/time field
    1. From a string
    2. From individual date-time components
    3. From an existing date/time object

    To use the lubridate helpere functions, you need to identify the order in which year, month and day appear in your dates in the string, then arange “y”, “m”, and “d” in the same order.

    ymd("2017-01-31")
    [1] "2017-01-31"
    mdy("January 31st, 2017")
    [1] "2017-01-31"
    mdy("Jan 31, 2017")
    [1] "2017-01-31"
    dmy("31-Jan-2017")
    [1] "2017-01-31"
    dmy("31-January-2017")
    [1] "2017-01-31"

    These functions also take unquote numbers. This is the most concise way to create a single date/time object

    ymd(20170101)
    [1] "2017-01-01"

    To add a time to a date, add an underscore and one or more h,m and s

    ymd_hm("2017-01-01 12:30")
    [1] "2017-01-01 12:30:00 UTC"

    YOu can force the creation of a time zone.

    ymd(20170101, tz = "UTC")
    [1] "2017-01-01 UTC"
    ymd_hm("2017-01-01 11:30", tz = "UTC")
    [1] "2017-01-01 11:30:00 UTC"
    mdy("Mar 7, 2018", tz = "UTC")
    [1] "2018-03-07 UTC"
    ymd_hm(201701011130, tz = "UTC")
    [1] "2017-01-01 11:30:00 UTC"

    From Individual Components

    When you want to get the individual components of the date-time spread across multiple columns.

    library(nycflights13)
    library(tidyverse)
    flights %>%
      select (year, month,day, hour, minute, arr_time)

    use make_date() for dates, or make_datetime() for date-times

    flights %>%
      select(year, month, day, hour, minute) %>%
      mutate(departure = make_datetime(year, month,day, hour, minute)
            )
    flights %>%
      head  (10)

    We need to use modulus arithmetic to pull out the hour and minute componennts. So 517 is 5 hours and 17 minutes. that is why we need to divide time by 100 and the remainder as minutes.

    make_datetime_100 <-  function(year, month, day, time){
      make_datetime(year, month, day, time %/% 100, time %% 100)
    }
    flights_dt <-  flights %>%
      filter(!is.na(dep_time), !is.na(arr_time)) %>%
      mutate(
        dep_time = make_datetime_100(year, month, day, dep_time),
        arr_time = make_datetime_100(year, month, day, arr_time),
        sched_dep_time = make_datetime_100(year, month, day, sched_dep_time),
        sched_arr_time = make_datetime_100(year, month, day, sched_arr_time)
      ) 
    flights_dt %>%
      select(origin, dest, ends_with("delay"), ends_with("time"))