Datas

A classe Date do R é a forma mais comum de guardar e tratar datas. Uma variável desta classe pode obtida, por exemplo, pela transformação de uma string usando a função as.Date.

dia<-as.Date("2018-01-01")
dia<-as.Date("01/01/2018")
dia
## [1] "0001-01-20"
dia<-as.Date("01/01/2018",format = '%d/%m/%Y')
dia
## [1] "2018-01-01"
# A função Sys.time permite obtermos a data atual, que pode ser convertida numa variável do tipo Date.

hoje<-Sys.time()
hoje
## [1] "2019-10-02 14:59:46 -03"
dataHoje<-as.Date(hoje)
dataHoje
## [1] "2019-10-02"
weekdays(dia)
## [1] "segunda-feira"
months(dia)
## [1] "janeiro"

Algumas questões:

Tibbles imprimem uma data como date. Já uma hora do dia imprime como time e data-hora é uma data mais uma hora (identifica unicamente um instante), no tibble tem-se dttm.

Nota: datas-horas são mais complexos de serem trabalhados, pois lidam com fusos horários.

Pacote lubridate

Pacote lubridate.

Pacote lubridate.

library(lubridate)
## Warning: package 'lubridate' was built under R version 3.6.1
## 
## Attaching package: 'lubridate'
## The following object is masked from 'package:base':
## 
##     date
today()
## [1] "2019-10-02"
now()
## [1] "2019-10-02 14:59:46 -03"
# As funções date() e as_date() assumem que a ordem segue o padrão da língua inglesa: ano-mês-dia (ymd).

as_date("2018-01-01")
## [1] "2018-01-01"
ymd("2018-01-01")
## [1] "2018-01-01"
mdy("January 01 st,2018")
## [1] "2018-01-01"
dmy("01-jan-2018")
## [1] "2018-01-01"
ymd(20180101)
## [1] "2018-01-01"

A função ymd também cria datas.

ymd_hms("2018-01-01 20:47:44")
## [1] "2018-01-01 20:47:44 UTC"
mdy_hm("01/01/2018 07:29")
## [1] "2018-01-01 07:29:00 UTC"
ymd(20180101, tz = "UTC")
## [1] "2018-01-01 UTC"
dt <- ymd_hms("2016-07-08 12:34:56")
c(year(dt), month(dt), day(dt), hour(dt), minute(dt), second(dt))
## [1] 2016    7    8   12   34   56

Funções úteis

O lubridate traz diversas funções para extrair os componentes de um objeto da classe date.

bday <- ymd_hms(19890729030142)
bday
## [1] "1989-07-29 03:01:42 UTC"
second(bday)
## [1] 42
day(bday)
## [1] 29
month(bday)
## [1] 7
year(bday)
## [1] 1989
wday(bday, label=TRUE)
## [1] sáb
## Levels: dom < seg < ter < qua < qui < sex < sáb
data <- dmy(01041991)
data
## [1] "1991-04-01"
hour(data)<-20
data
## [1] "1991-04-01 20:00:00 UTC"
c(yday(data), wday(data))
## [1] 91  2

Outro jeito de criar datas é passando seus componentes individuais para make_date() e make_datetime(). Este método é particularmente útil quando tratando tabelas.

make_date(2018, 01, 20)
## [1] "2018-01-20"
make_datetime(2018, 01, 20,40,55)
## [1] "2018-01-21 16:55:00 UTC"

Arredondamento

As funções floor_date(), round_date() e ceiling_date() servem para fazermos arredondamento de datas.

day<-make_datetime(2018, 01,16,40,58)
round_date(day,"hour")
## [1] "2018-01-17 17:00:00 UTC"
floor_date(day,"hour")
## [1] "2018-01-17 16:00:00 UTC"
ceiling_date(day,"hour")
## [1] "2018-01-17 17:00:00 UTC"

Durações

as.duration(today() - dmy("28/12/1995"))
## [1] "749865600s (~23.76 years)"
as.duration(128369329)
## [1] "128369329s (~4.07 years)"
dseconds(100)
## [1] "100s (~1.67 minutes)"
dminutes(100)
## [1] "6000s (~1.67 hours)"
dhours(100)
## [1] "360000s (~4.17 days)"
ddays(100)
## [1] "8640000s (~14.29 weeks)"
dweeks(100)
## [1] "60480000s (~1.92 years)"
dyears(1)
## [1] "31536000s (~52.14 weeks)"
# Durações sempre registram o tempo em segundos.
3*dyears(1) + 2*dweeks(12) + dhours(18)
## [1] "109188000s (~3.46 years)"

Períodos

Como nem sempre queremos diferenças de tempo e aritmética com datas resumidas a uma duração em segundos, o lubridate fornece-nos o conceito de períodos (durações que são legíveis para um humano).

weeks(17)
## [1] "119d 0H 0M 0S"
days(19)
## [1] "19d 0H 0M 0S"
years(2) + weeks(24) + hours(19)
## [1] "2y 0m 168d 19H 0M 0S"
# Veja por exemplo o que acontece quando adicionamos dyears(1) e years(1) a um ano bissexto:

c(ymd("2016-01-01") + dyears(1), ymd("2016-01-01") + years(1))
## [1] "2016-12-31" "2017-01-01"
# Comparado com durações, períodos têm maior propensão de fazer o que você espera.

Intervalos

Imagine que precisamos determinar quantos dias cabem em um mês. Isso naturalmente depende porque nem todo mês tem o mesmo número de dias.

months(1) / days(1)
## estimate only: convert to intervals for accuracy
## [1] 30.4375
#  Usando o operador infixo %--%, determinamos um intervalo e assim fica fácil de obter um resultado preciso:

(today() %--% (today() + months(1))) / days(1)
## [1] 31
inicio <- dmy("01-04-1991")
evento <- dmy("31-10-1993")
sobrev <- interval(inicio, evento)
sobrev
## [1] 1991-04-01 UTC--1993-10-31 UTC
# Podemos verificar se dois intervalos tem intersecção com a função int_overlaps().
intervalo_1 <- dmy("01-02-2003") %--% dmy("02-03-2005")

intervalo_2 <- dmy("04-05-2004") %--% dmy("12-03-2012")  

int_overlaps(intervalo_1, intervalo_2)
## [1] TRUE

Fusos horários

Uma característica inerente das datas é o fuso horário. Se você estiver trabalhando com datas de eventos no Brasil e na Escócia, por exemplo, é preciso verificar se os valores seguem o mesmo fuso horário. A

Além disso, quando a data exata de um evento for relevante, você pode precisar converter horários para outros fusos para comunicar seus resultados em outros países.

Sys.timezone() # qual o fuso horário que estamos
## [1] "America/Sao_Paulo"
data <- ymd_hms("2017-07-16 22:00:00", tz = "America/Sao_Paulo")
data
## [1] "2017-07-16 22:00:00 -03"
with_tz(data, tzone = "GMT")
## [1] "2017-07-17 01:00:00 GMT"
force_tz(data, tzone = "GMT") # mudando o fuso horário
## [1] "2017-07-16 22:00:00 GMT"

Nota: O lubridate sempre usa o UTC (Tempo Universal Coordenado) que é o fuso horário padrão usado pela comunidade científica e aproximadamente equivale ao seu predecessor GMT (Tempo Médio de Greenwich). Não tem um horário de verão.

library(nycflights13)
## Warning: package 'nycflights13' was built under R version 3.6.1
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 3.6.1
## Registered S3 methods overwritten by 'ggplot2':
##   method         from 
##   [.quosures     rlang
##   c.quosures     rlang
##   print.quosures rlang
## -- Attaching packages --------------------------------------------------- tidyverse 1.2.1 --
## v ggplot2 3.1.1     v purrr   0.3.2
## v tibble  2.1.1     v dplyr   0.8.3
## v tidyr   1.0.0     v stringr 1.4.0
## v readr   1.3.1     v forcats 0.4.0
## Warning: package 'tidyr' was built under R version 3.6.1
## Warning: package 'dplyr' was built under R version 3.6.1
## -- Conflicts ------------------------------------------------------ tidyverse_conflicts() --
## x lubridate::as.difftime() masks base::as.difftime()
## x lubridate::date()        masks base::date()
## x dplyr::filter()          masks stats::filter()
## x lubridate::intersect()   masks base::intersect()
## x dplyr::lag()             masks stats::lag()
## x lubridate::setdiff()     masks base::setdiff()
## x lubridate::union()       masks base::union()
flights %>% select(year,month,day,hour,minute)
# Para criar uma data/hora a partir desse tipo de entrada, use make_date() para datas ou make_datetime() para datas-horas:

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

Atividade:

Dica: arremessos são representados pela categoria shot da coluna etype.