Trabalhando com datas II – Lubridate

Simplificando

Biblioteca Lubridate

Mostramos no post anterior que trabalhar com datas pode ser algo bem confuso. Como esse é um problema bem comum outras pessoas já criaram algumas formas de o tratar.

Se nosso post anterior não foi o suficiente para complicar as coisas ao mostrar os objetos POSIXct, POSIXlt, Date:

https://dadosdadosdados.wordpress.com/2015/07/10/trabalhando-com-datas/

Note que o Lubridate é compatível com objetos POSIXct, POSIXlt, Date, chron, timeDate, zoo, xts, its, tis, timeSeries, fts e tseries. (xts, zoo e timeseries são troços bem pentelhos de se trabalhar…)

Carregando a biblioteca

library(lubridate)

Comparando operações

Vamos fazer algumas brincadeiras comparando os métodos para ’12/02/15′ (12/fev/15)

R básico

Primeiro, vamos descobrir em que ‘time zone’ estamos, para esse exercício é irrelevante, mas geralmente o R reconhece datas em ‘time zones’ que não são os nossos e temos que ficar ajustando isso o tempo todo.

Sys.timezone(location = TRUE)
## [1] "America/Sao_Paulo"
  1. Primeiro criamos a variável date
date <- as.POSIXct("12-02-2015",format = "%d-%m-%Y")
date
## [1] "2015-02-12 BRST"
  1. Para extrair o mês usamos:
as.numeric(format(date, "%m"))
## [1] 2
  1. Como trocar o mês?
as.POSIXct(format(date,"%Y-10-%d"), tz = "UTC")
## [1] "2015-10-12 UTC"
  1. Operações com datas
    • Ontem
seq(date, length = 2,by = "-1 day")[2]
## [1] "2015-02-11 BRST"
  • Trocando ‘time zone’
as.POSIXct(format(as.POSIXct(date), tz = "America/Sao_Paulo"), tz = "GMT")
## [1] "2015-02-12 GMT"

Lubridate

Traduzindo as operações acima para Lubridate

date <- dmy("12-02-2015")
month(date)
## [1] 2
month(date) <- 10
date - days(1)
## [1] "2015-10-11 UTC"
with_tz(date, "GMT")
## [1] "2015-10-12 GMT"

Note que o Lubridate faz o cálculo das horas na troca do ‘time zone’. Como na maioria das vezes nós precisamos simplesmente arrumar a ‘time zone’ que está errada, usamos o comando: force_tz(). (a não ser que a ‘tz’ seja UTC)

force_tz(date,'GMT')
## [1] "2015-10-12 GMT"

De texto para data

Mesmo com o lubridate simplificando o processo, nós ainda não escapamos de ter que dizer para o R qual é o formato em que as datas estão aparecendo, para isso temos as funções:

  • ymd()
  • mdy()
  • dmy()
mdy("12-02-2015")
## [1] "2015-12-02 UTC"
mdy("12/02/2015")
## [1] "2015-12-02 UTC"
mdy("12/2/15")
## [1] "2015-12-02 UTC"

Independente de como estiver escrita a data, o lubridate é capaz de interpretar e converter.

dmy("12-02-2015")
## [1] "2015-02-12 UTC"
dmy("12/02/2015")
## [1] "2015-02-12 UTC"
dmy("12/2/15")
## [1] "2015-02-12 UTC"

Se as datas estiverem em outro formato, só precisamos inverter o comando.

Operações com datas

Outro aspecto que o lubridate facilita bastante são as operações com datas.

Criando um vetor de datas

dmy("12/2/15") + days(0:9)
##  [1] "2015-02-12 UTC" "2015-02-13 UTC" "2015-02-14 UTC" "2015-02-15 UTC"
##  [5] "2015-02-16 UTC" "2015-02-17 UTC" "2015-02-18 UTC" "2015-02-19 UTC"
##  [9] "2015-02-20 UTC" "2015-02-21 UTC"
dmy("12/2/15") + months(0:9)
##  [1] "2015-02-12 UTC" "2015-03-12 UTC" "2015-04-12 UTC" "2015-05-12 UTC"
##  [5] "2015-06-12 UTC" "2015-07-12 UTC" "2015-08-12 UTC" "2015-09-12 UTC"
##  [9] "2015-10-12 UTC" "2015-11-12 UTC"
dmy("12/2/15") + years(0:9)
##  [1] "2015-02-12 UTC" "2016-02-12 UTC" "2017-02-12 UTC" "2018-02-12 UTC"
##  [5] "2019-02-12 UTC" "2020-02-12 UTC" "2021-02-12 UTC" "2022-02-12 UTC"
##  [9] "2023-02-12 UTC" "2024-02-12 UTC"

Subtração

dataIni <- dmy("12/02/15")
dataFim <- dmy("12/10/2015")

dataFim-dataIni
## Time difference of 242 days

Por muito mais tempo do que gostaríamos de admitir acreditávamos que o R forçava a ‘time zone’ UTC de forma errada nas nossas datas e ficávamos forçando a ‘time zone’ “America/Sao_Paulo” em todas nossas operações, porém UTC não é exatamente um fuso horário e sim um padrão por onde os centros que controlam/acompanham as horas concordaram em manter sincronizados.

http://www.timeanddate.com/time/aboututc.html

Acima podemos ver que a diferença entre as datas são 242 dias ‘redondos’. Vamos fazer a mesma conta forçando um ‘time zone’

dataIni <- dmy("12/02/15", tz='America/Sao_Paulo')
dataFim <- dmy("12/10/15", tz='America/Sao_Paulo')

dataFim-dataIni
## Time difference of 242.0417 days

Agora, a diferença leva em consideração horário de verão onde o 0.0417 dia é aproximadamente igual a 01 hora.

Duration vs Period

Basicamente temos dois tipos de unidades para se calcular tempo no R com o lubridate, unidades relativas e unidades exatas. Isso pode ser um ponto de atenção quando fazemos operações, pois temos eventos como horário de verão e anos bissextos que podem atrapalhar as operações, por exemplo:

365 dias = 01 ano

dmy('01-01-11') + days(365)
## [1] "2012-01-01 UTC"
dmy('01-01-11') + years(1)
## [1] "2012-01-01 UTC"

365 dias != 01 ano

dmy('01-01-12') + days(365)
## [1] "2012-12-31 UTC"
dmy('01-01-12') + years(1)
## [1] "2013-01-01 UTC"

Bagunçando tudo… Durações…

dmy('01-01-12') + days(365)
## [1] "2012-12-31 UTC"
dmy('01-01-12') + dyears(1)
## [1] "2012-12-31 UTC"

Nos cálculos acima temos dois cenários, no primeiro usamos ‘periods’ que são mais intuitivos, mas são unidades de tempo que não possuem tamanhos consistentes, ou seja, somar 365 dias em um ano ‘normal’ adiciona um ano, porém adicionar um ano sempre vai adicionar um ano, independente se é um ano bissexto ou não. O mesmo funciona com horas em dias que possuem horário de verão.

Em oposição, temos as ‘durations’ que são unidades consistentes de tempo (segundo a documentação, calculadas em segundos) e essas unidades são sempre consistentes, ou seja, adicionar um ano (dyear()) vai sempre adicionar o equivalente a um ano em segundos, independente se estamos em um ano bissexto ou não.

Pessoalmente achamos raras as situações em que precisamos utilizar ‘durations’, mas é bom entender a diferença.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s