8 Trabalhando com datas
Datas são um caso a parte no R. Existe uma própria classe para objetos desse tipo, chamada Date, com D maiúsculo. O R lida com datas no formato AAAA-MM-DD (Ano, Mês e Dia).
Abaixo, definimos um vetor com datas
## [1] "2014-07-15" NA "2019-12-31" NA
## [1] "Date"
Perceba que o R nativamente não aceita qualquer separador entre o ano, o mês e o dia, apenas o traço. O pacote lubridate, que faz parte da família tidyverse, possui uma versão mais generalizável para isso:
##
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
##
## date, intersect, setdiff, union
## [1] "2014-07-15" "2018-03-20" "2019-12-31" "2017-05-11"
A propósito, dominar o pacote lubridate, que possui funções muito simples de usar, é a única coisa necessária para saber lidar com datas no R. Por isso, este capítulo se dedica a mostrar as principais funções do pacote.
8.1 Gerar um vetor sequencial de datas
Essa tarefa é feita usando uma função nativa do R chamada seq.Date(), que possui quatro argumentos principais, sendo que três deles precisam ser especificados.
## function (from, to, by, length.out = NULL, along.with = NULL,
## ...)
## NULL
# gerar vetor de datas separadas por mes
seq.Date(from = as_date("2020-01-01"),
to = as_date("2020-12-01"),
by = "1 month")## [1] "2020-01-01" "2020-02-01" "2020-03-01" "2020-04-01" "2020-05-01"
## [6] "2020-06-01" "2020-07-01" "2020-08-01" "2020-09-01" "2020-10-01"
## [11] "2020-11-01" "2020-12-01"
# gerar vetor de datas separadas por dia
seq.Date(from = as_date("2020-01-01"),
to = as_date("2020-01-20"),
by = "1 day")## [1] "2020-01-01" "2020-01-02" "2020-01-03" "2020-01-04" "2020-01-05"
## [6] "2020-01-06" "2020-01-07" "2020-01-08" "2020-01-09" "2020-01-10"
## [11] "2020-01-11" "2020-01-12" "2020-01-13" "2020-01-14" "2020-01-15"
## [16] "2020-01-16" "2020-01-17" "2020-01-18" "2020-01-19" "2020-01-20"
# gerar vetor de datas separadas por 3 dias
seq.Date(from = as_date("2020-01-01"),
to = as_date("2020-01-20"),
by = "3 day")## [1] "2020-01-01" "2020-01-04" "2020-01-07" "2020-01-10" "2020-01-13"
## [6] "2020-01-16" "2020-01-19"
# gerar um vetor de 7 semanas separados por 1 semana
seq.Date(from = as_date("2020-01-01"),
length.out = 7,
by = "1 week")## [1] "2020-01-01" "2020-01-08" "2020-01-15" "2020-01-22" "2020-01-29"
## [6] "2020-02-05" "2020-02-12"
8.2 ‘Parsear’ datas e horários
Para fazer o R converter (ou parsear na linguagem de programação) um string em data, basta usar as funções correspondentes do lubridate.
Por exemplo, no vetor de exemplo x, definido acima, as datas já estavam definidas no formato correto: AAAA-MM-DD. Aqui no Brasil usamos outro formato: DD/MM/AAAA. O lubridate possui uma função pronta para essa situação:
# observer como usamos diferentes separadores
datas_brasil <- c("01/12/2019", "20/11/2018", "30011990", "17-03-2000")
# parseando o vetor acima para Data
dmy(datas_brasil)## [1] "2019-12-01" "2018-11-20" "1990-01-30" "2000-03-17"
Caso o vetor também contenha dados de horário, basta incluir o sufixo referente a hora, minuto e segundo:
## [1] "2019-09-30 14:51:39 UTC"
## [1] "2019-09-30 14:15:00 UTC"
## [1] "2019-09-30 15:00:00 UTC"
8.3 Extrair componentes de uma data
É possível extrair qualquer tipo de componente de uma data ou de um vetor de datas com o lubridate. Veja alguns exemplos:
datas_brasil <- dmy_hms(c("01/12/2019 13:51:15", "20/11/2018 00:00:00", "30011990 080000", "17-03-2000 203000"))
datas_brasil## [1] "2019-12-01 13:51:15 UTC" "2018-11-20 00:00:00 UTC"
## [3] "1990-01-30 08:00:00 UTC" "2000-03-17 20:30:00 UTC"
## [1] 2019 2018 1990 2000
## [1] 12 11 1 3
## [1] 1 20 30 17
## [1] 48 47 5 11
## [1] dom ter ter sex
## Levels: dom < seg < ter < qua < qui < sex < sáb
## [1] 4 4 1 1
## [1] 13 0 8 20
8.4 Operações matemáticas com datas
Geralmente se está interessado em fazer três tipos de operações matemáticas com datas:
- Adicionar uma quantidade N de dias/meses/anos/etc em uma data:
## [1] "2019-12-08 13:51:15 UTC" "2018-11-27 00:00:00 UTC"
## [3] "1990-02-06 08:00:00 UTC" "2000-03-24 20:30:00 UTC"
## [1] "2020-02-29 13:51:15 UTC" "2019-02-18 00:00:00 UTC"
## [3] "1990-04-30 08:00:00 UTC" "2000-06-15 20:30:00 UTC"
## [1] "2020-11-30 19:51:15 UTC" "2019-11-20 06:00:00 UTC"
## [3] "1991-01-30 14:00:00 UTC" "2001-03-18 02:30:00 UTC"
- Calcular a diferença de tempo entre duas datas:
No R, subtrair datas segue a mesma sintaxe de subtrair números:
data1 <- dmy_hms("01/09/1993 20:00:00")
data2 <- dmy_hms("24-06-2018 17:00:00")
dif <- data2 - data1
dif## Time difference of 9061.875 days
Por padrão, o R retorna a diferença em dias, mas em um objeto de classe difftime.
## [1] "difftime"
Recomenda-se então converter o output para a classe numeric:
## [1] 9061.875
Caso se deseje calcular essa diferença em outras unidades de tempo, como meses ou semanas, basta fazer a divisão correspondente:
## [1] 1294.554
## [1] 302.0625
## [1] 24.82705
- Arredondar datas:
Para arredondar uma data, por exemplo, retornar o primeiro ou último dia da semana/mês/trimestre/etc de uma data de referência, usa-se as funções ceiling_date() (arredondar para cima) e floor_date() (para baixo):
## [1] "2019-12-01 UTC" "2018-11-18 UTC" "1990-01-28 UTC" "2000-03-12 UTC"
# retornar a ultima data do mês
# por padrao, ceiling_date retorna a primeira data do próximo mês,
# por isso é necessario subtrair o resultado por 1
ceiling_date(datas_brasil, "month") - 1## [1] "2019-12-31 23:59:59 UTC" "2018-11-30 23:59:59 UTC"
## [3] "1990-01-31 23:59:59 UTC" "2000-03-31 23:59:59 UTC"
## [1] "2019-12-01 13:00:00 UTC" "2018-11-20 00:00:00 UTC"
## [3] "1990-01-30 08:00:00 UTC" "2000-03-17 20:00:00 UTC"