Análise de Dados em R (FNDE) - Módulo 2

Sessão 5 - Trabalhando com Datas - Lubridate

Allan Vieira
julho de 2018

Objetivos



  • aprender as principais funções do pacote lubridate;

  • trabalhar com datas no R.

Pacote lubridate - Introdução

  • trabalhar com datas (e tempos) no base R geralmente era um processo frustrante

  • as funções “nativas” do R para dados do tipo date-times são pouco intuitivas e mudam dependendo do tipo de objeto que está sendo usado;

  • Datas e tempos têm uma série de especificidades, como por exemplo fusos, anos bissextos, horários de verão, etc;

  • Por isso precisamos ter métodos robustos para lidar com esses tipos de peculiaridades;

  • O pacote lubridate nos facilita algumas operações que já existiam no base R e abre a possibilidade de outras que não haviam.

Transformação de números e strings em datas (1)

  • ** DD/MM/YYYY estar em número ou string não é a mesma coisa que estar no formato de data !!**

  • o R possui uma classe específica para indicar datas

  • Dito isso, …

  • Algumas funções interessantes são: ymd(), ymd_hms, dmy(), dmy_hms, mdy(), etc. ??lubridate.

library(lubridate)
ymd(20101215)
[1] "2010-12-15"
mdy("4/1/17")
[1] "2017-04-01"
  • Você pode ir variando as letras das funções acima, dependendo de como seus dados estão organizados.

Transformação de números e strings em datas (2)

A informação mais completa de data-hora que você pode ter no R é:

arrive <- ymd_hms("2011-06-04 12:00:00", tz = "Pacific/Auckland")
arrive
[1] "2011-06-04 12:00:00 NZST"
#> [1] "2011-06-04 12:00:00 NZST"
leave <- ymd_hms("2011-08-10 14:00:00", tz = "Pacific/Auckland")
leave
[1] "2011-08-10 14:00:00 NZST"
# help(ymd_hms)

# para verificar as timezone disponíveis:
#str_subset(OlsonNames(), "Brazil")
# ou grep("Brazil", OlsonNames(), )

Extração de partes de data e tempo (1)

year(), month(), mday(), hour(), minute() and second():

bday <- dmy("02/01/1984")
month(bday)
[1] 1
month(bday, label=TRUE)
[1] Jan
12 Levels: Jan < Feb < Mar < Apr < May < Jun < Jul < Aug < Sep < ... < Dec
wday(bday)
[1] 2
wday(bday, label = TRUE)
[1] Mon
Levels: Sun < Mon < Tue < Wed < Thu < Fri < Sat
year(bday) <- 2016
wday(bday, label = TRUE)
[1] Sat
Levels: Sun < Mon < Tue < Wed < Thu < Fri < Sat

Extração de partes de data e tempo (2)

now()
[1] "2018-12-09 03:29:15 -02"
today()
[1] "2018-12-09"
second(arrive)
[1] 0
second(arrive) <- 25
arrive
[1] "2011-06-04 12:00:25 NZST"
second(arrive) <- 0

Lidando com fuso-horários (time zones):

time <- ymd_hms("2010-12-13 15:30:30")
time
[1] "2010-12-13 15:30:30 UTC"
# Diz a hora que seria "time" em outro fuso
with_tz(time, "America/Chicago")
[1] "2010-12-13 09:30:30 CST"
# Mantém o print da hora, mas muda região
force_tz(time, "America/Chicago")
[1] "2010-12-13 15:30:30 CST"

Intervalos de tempo (1)

  • Você pode salvar intervalos de tempo em lubridate como uma classe Interval;
  • Isso nos permite as criar as seguintes operações:
# Primeiro, criamos um intervalo:
auckland <- interval(arrive, leave) 
auckland
[1] 2011-06-04 12:00:00 NZST--2011-08-10 14:00:00 NZST
#> [1] 2011-06-04 12:00:00 NZST--2011-08-10 14:00:00 NZST
auckland <- arrive %--% leave
auckland
[1] 2011-06-04 12:00:00 NZST--2011-08-10 14:00:00 NZST

Intervalos de tempo (2)

E podemos verificar por exemplo se esse intervalo faz overlap (sobrepõe) com algum outro intervalo que já temos.

jsm <- interval(ymd(20110720, tz = "Pacific/Auckland"), ymd(20110831, tz = "Pacific/Auckland"))
jsm
[1] 2011-07-20 NZST--2011-08-31 NZST
# há sobreposição?
int_overlaps(jsm, auckland)
[1] TRUE
# quando ocorre sobreposição?
setdiff(auckland, jsm)
[1] 2011-06-04 12:00:00 NZST--2011-07-20 NZST

Outras funções que lidam com intervalos são: int_start, int_end, int_flip, int_shift, int_aligns, union, intersect, setdiff e %within%.

Operações aritméticas com data e horas (1)

  • Intervalos são um tipo específico de espaço de tempo;
  • Além deles, lubridate disponibiliza outras duas classes genéricas para trabalharmos com espaços de tempo: Durations e Periods.
minutes(2) ## period
[1] "2M 0S"
dminutes(2) ## duration
[1] "120s (~2 minutes)"

Operações aritméticas com data e horas (2)

  • Por que 2 classes?

  • Durations vão sempre gerar resultados precisos em termos de tempo, considerando, por exemplo, se o ano é bissexto ou não;

  • Periods, por sua vez, vão se basear na number line, desconsiderando detalhes como anos bissextos etc.

  • Ambas as classes serão úteis para fazermos operações aritméticas com datas, dependendo do nosso objetivo.

Operações aritméticas com data e horas (3)

leap_year(2011) ## regular year
[1] FALSE
leap_year(2012) ## leap year
[1] TRUE
ymd(20120101) + dyears(1)
[1] "2012-12-31"
# dyears(1) sempre somará considerando se o ano é bissexto ou não

ymd(20120101) + years(1)
[1] "2013-01-01"
  • Durations foi “honesta” na presença do ano bissexto, o que resulta em um dia a menos na soma, devido ao dia a mais em fevereiro.

Operações aritméticas com data e horas (4)

Para saber quanto tempo em dias, semanas ou minutos você passou no seu compromisso em Auckland:

auckland / ddays(1)
[1] 67.08333
auckland / dweeks(1)
[1] 9.583333
auckland / dminutes(1)
[1] 96600

Para não termos que ficar trabalhando com frações de meses ou semanas por exemplo, podemos utilizar módulo:

auckland %/% months(1)
[1] 2
auckland %% months(1)
[1] 2011-08-04 12:00:00 NZST--2011-08-10 14:00:00 NZST

Operações aritméticas com data e horas (5)

Outros exemplos:

x <- dmy(02011984)

year(x) + 34
[1] 2018
day(x) -1
[1] 1
month(x)*2
[1] 2

Mais detalhes sobre lubridate em http://lubridate.tidyverse.org.

FIM

OBRIGADO!!