Artigo escrito com a colaboração de Erick Araújo
As datas são objetos frequentes e importantes quando se trabalha com análise de dados. Saber lidar com o seu manuseio é de grande importância para o trabalho do analista. Sendo assim, este artigo tem como objetivo reunir informações e nortear o leitor quanto as várias possibilidades de manipulação de objetos desse tipo.
O R Base possui algumas funções que permitem a manipulação e o tratamento de objetos do tipo data, porém, em alguns contextos, essas funções apresentam limitações e o seu uso é pouco intuitivo. Mas graças ao Jedi do R Hadley Wickham, essas limitações podem ser contornadas facilmente com o auxílio do pacote lubridate.
O lubridate é um pacote do ecossistema Tidyverse, e talvez o pacote mais completo para se trabalhar com datas no R. Nesse artigo, abordaremos suas principais aplicações e para isso, vamos utilizar um banco de dados com três diferentes formatos de datas e observar como algumas funções se comportam.
Pacotes
library(tidyverse) # Principal pacote do ecossistema tidyverse, usado para diversas manipulações.
library(rhandsontable) # Pacote utilizado para construção de tabelas.
library(lubridate) # Pacote utilizado para manipulação de datas
# (Após o carregamento do tidyverse, não é necessário carregar o lubridate novamente)
Lubridate
as_date()
dados %>%
mutate(formato_1 = as_date(formato_1),
formato_2 = as_date(formato_2),
formato_3 = as_date(formato_3))
## # A tibble: 5 x 3
## formato_1 formato_2 formato_3
## <date> <date> <date>
## 1 2009-02-09 NA NA
## 2 2009-02-09 NA NA
## 3 2009-02-09 NA NA
## 4 2009-02-09 NA NA
## 5 2018-04-02 NA NA
O as_date() é o comando mais básico para se transformar um objeto em uma data no lubridate. Podemos observar que para a nossa primeira variável, a transformação acontece de maneira direta como o esperado.
Para os dois outros casos a função não reconhece os formatos fornecidos dentro dos objetos, retornando um valor ausente.
Para o lubridate, lidar com estruturas pouco usuais de datas não é um problema, e o objetivo de transformação pode ser alcançado com poucas linhas de código:
dados %>%
mutate(formato_1 = as_date(formato_1),
formato_2 = my(formato_2),
formato_3 = dmy(formato_3))
## # A tibble: 5 x 3
## formato_1 formato_2 formato_3
## <date> <date> <date>
## 1 2009-02-09 NA 2009-02-09
## 2 2009-02-09 NA 2009-02-09
## 3 2009-02-09 NA 2009-02-09
## 4 2009-02-09 NA 2009-02-09
## 5 2018-04-02 NA 2018-04-02
Erro!
O Lubridate possui algumas funções para especificar o formato em que o nosso objeto tipo data foi disposto. Essas funções são:
dmy(), mdy(), myd(), ymd(), ydm(), onde “d”, “m”, “y”, representam o dia, mês e ano respectivamente. Basta especificar a ordem do objeto em questão. Também podemos trabalhar com datas abreviadas como é o caso da coluna ‘formato_2’ do nosso conjunto de dados. Porém o comando reconhecerá apenas a abreviação escrita em inglês.
exemplo4 <- c('feb/2019')
exemplo4 %>% my()
## [1] "2019-02-01"
exemplo5 <- c('February/2019')
exemplo5 %>% my()
## [1] "2019-02-01"
Vamos fazer a tradução do nosso conjunto de dados e aplicar a função para ver seu funcionamento:
dados2
## # A tibble: 5 x 3
## formato_1 formato_2 formato_3
## <chr> <chr> <chr>
## 1 2009-02-09 feb/2009 09022009
## 2 2009-02-09 feb/2009 09022009
## 3 2009-02-09 feb/2009 09022009
## 4 2009-02-09 feb/2009 09022009
## 5 2018-04-02 apr/2018 02042018
dados2 %>%
mutate(formato_1 = as_date(formato_1),
formato_2 = my(formato_2),
formato_3 = dmy(formato_3))
## # A tibble: 5 x 3
## formato_1 formato_2 formato_3
## <date> <date> <date>
## 1 2009-02-09 2009-02-01 2009-02-09
## 2 2009-02-09 2009-02-01 2009-02-09
## 3 2009-02-09 2009-02-01 2009-02-09
## 4 2009-02-09 2009-02-01 2009-02-09
## 5 2018-04-02 2018-04-01 2018-04-02
Agora nossas três variáveis foram definidas como data corretamente. É muito comum também, em alguns cenários, lidarmos com datas cuja precisão abrange até os segundos, para isso, existem também, no lubridate, funções para trabalhar com datas no formato dttm:
# criando um objeto data com precisão de segundos, objeto dttm:
data_dttm <- c('2009-02-09, 17:12:53')
ymd_hms(data_dttm)
## [1] "2009-02-09 17:12:53 UTC"
É possível também permutar as letras para outras combinações de data e hora. Exemplo: dmy_hms(), ymd_hms() e etc…
Extraindo valores
Extrair valores com o lubridate é bem simples, pois existem funções específicas para cada categoria, vejamos abaixo um exemplo de extração do ano:
dados2 %>%
mutate(formato_1 = as_date(formato_1),
formato_2 = my(formato_2),
formato_3 = dmy(formato_3),
ano = year(formato_1))
## # A tibble: 5 x 4
## formato_1 formato_2 formato_3 ano
## <date> <date> <date> <dbl>
## 1 2009-02-09 2009-02-01 2009-02-09 2009
## 2 2009-02-09 2009-02-01 2009-02-09 2009
## 3 2009-02-09 2009-02-01 2009-02-09 2009
## 4 2009-02-09 2009-02-01 2009-02-09 2009
## 5 2018-04-02 2018-04-01 2018-04-02 2018
Funções úteis
second() – extrai os segundos.
minute() – extrai os minutos.
hour() – extrai a hora.
wday() – extrai o dia da semana.
mday() – extrai o dia do mês.
month() – extrai o mês.
year() – extrai o ano.
Fuso horário
Existem duas principais funções para se trabalhar com fuso horário no lubridate, with_tz() e force_tz(). Vejamos um exemplo de como usa-la:
# função now(), retorma o momento exato em que o código for executado
exemplo_fuso <- now()
exemplo_fuso
## [1] "2022-03-23 16:14:08 -03"
# Devolve qual seria a data em outro fuso
with_tz(exemplo_fuso, tz = "America/New_York")
## [1] "2022-03-23 15:14:08 EDT"
# Altera o fuso sem mudar o horário
force_tz(exemplo_fuso, tz = "America/New_York")
## [1] "2022-03-23 16:14:08 EDT"
Operações com datas
A função today() retorna um objeto data com os valores do dia em que o código for executado. Com isso, vamos criar um vetor com essa função para observar algumas operações:
dados2 <- dados2 %>%
mutate(formato_1 = as_date(formato_1),
formato_2 = my(formato_2),
formato_3 = dmy(formato_3),
ano = year(formato_1),
hoje = today())
dados2
## # A tibble: 5 x 5
## formato_1 formato_2 formato_3 ano hoje
## <date> <date> <date> <dbl> <date>
## 1 2009-02-09 2009-02-01 2009-02-09 2009 2022-03-23
## 2 2009-02-09 2009-02-01 2009-02-09 2009 2022-03-23
## 3 2009-02-09 2009-02-01 2009-02-09 2009 2022-03-23
## 4 2009-02-09 2009-02-01 2009-02-09 2009 2022-03-23
## 5 2018-04-02 2018-04-01 2018-04-02 2018 2022-03-23
Assim podemos fazer uma subtração direta entre os vetores (Ex: hoje – formato_1), já que estão no formato padrão de datas no R. Ou usar também usar a função interval() que salva o intervalo entre duas datas em um objeto.
dados2 %>%
mutate(diferenca = hoje - formato_1)
## # A tibble: 5 x 6
## formato_1 formato_2 formato_3 ano hoje diferenca
## <date> <date> <date> <dbl> <date> <drtn>
## 1 2009-02-09 2009-02-01 2009-02-09 2009 2022-03-23 4790 days
## 2 2009-02-09 2009-02-01 2009-02-09 2009 2022-03-23 4790 days
## 3 2009-02-09 2009-02-01 2009-02-09 2009 2022-03-23 4790 days
## 4 2009-02-09 2009-02-01 2009-02-09 2009 2022-03-23 4790 days
## 5 2018-04-02 2018-04-01 2018-04-02 2018 2022-03-23 1451 days
dados2 %>%
mutate(intervalo = interval(formato_1, hoje)) %>% select(intervalo)
## # A tibble: 5 x 1
## intervalo
## <Interval>
## 1 2009-02-09 UTC--2022-03-23 UTC
## 2 2009-02-09 UTC--2022-03-23 UTC
## 3 2009-02-09 UTC--2022-03-23 UTC
## 4 2009-02-09 UTC--2022-03-23 UTC
## 5 2018-04-02 UTC--2022-03-23 UTC
Vamos definir um intervalo com o operador %–%, e ainda verificar se existe uma intersecção com a função int_overlaps().
intervalo_1 <- dmy("09-02-2009") %--% dmy("09-02-2010")
intervalo_2 <- dmy("09-08-2009") %--% dmy("09-08-2010")
int_overlaps(intervalo_1, intervalo_2)
## [1] TRUE
Duração de um intervalo
dados2 %>%
mutate(intervalo = interval(formato_1, hoje),
duracao_dias = intervalo/ddays()) %>% select(intervalo, duracao_dias)
## # A tibble: 5 x 2
## intervalo duracao_dias
## <Interval> <dbl>
## 1 2009-02-09 UTC--2022-03-23 UTC 4790
## 2 2009-02-09 UTC--2022-03-23 UTC 4790
## 3 2009-02-09 UTC--2022-03-23 UTC 4790
## 4 2009-02-09 UTC--2022-03-23 UTC 4790
## 5 2018-04-02 UTC--2022-03-23 UTC 1451
Além das funções citadas, o pacote lubridate oferece várias outras opções de manipulação e manuseio de datas. Visite a documentação do pacote clicando AQUI.