12.5 Intervalos de tempo regulares e irregulares

A time series can either be irregular (unequally spaced), strictly regular (equally spaced) or have an underlying regularity, i.e., be created from a regular series by omitting some observations. Here, the latter property is called regular. Consequently, regularity follows from strict regularity but not vice versa. ?zoo::is.regular

  • Estritamente regular: dados temporais igualmente espaçados.
  • Regular: dados temporais igualmente espaçados com omissão de algumas observações.
  • Irregular: dados temporais desigualmente espaçados.

Exemplo 12.1 Adaptado da documentação de zoo::is.regular.

library(zoo)
# estritamente regular
(z <- zoo(1:10, seq(2000, 2002.25, by = 0.25), frequency = 4))
## 2000 Q1 2000 Q2 2000 Q3 2000 Q4 2001 Q1 2001 Q2 2001 Q3 2001 Q4 2002 Q1 2002 Q2 
##       1       2       3       4       5       6       7       8       9      10
is.regular(z)
## [1] TRUE
is.regular(z, strict = TRUE)
## [1] TRUE
# regular, omitindo a terceira posição
is.regular(z[-3])
## [1] TRUE
is.regular(z[-3], strict = TRUE)
## [1] FALSE
## irregular
set.seed(42); (z <- zoo(1:10, rnorm(10)))
## -0.5647 -0.1061 -0.0947 -0.0627  0.3631  0.4043  0.6329   1.371  1.5115  2.0184 
##       2       6       8      10       3       5       4       1       7       9
is.regular(z)
## [1] FALSE
is.regular(z, strict = TRUE)
## [1] FALSE

12.5.1 ts - Time Series

O função ts() do pacote stats é utilizada para criar objetos de séries temporais estritamente regulares. Usualmente definem-se os argumentos start e end ou start e frequency.

ts(1:10, start = 2010, end = 2019) # 10 observações anuais de 2010 a 2019
## Time Series:
## Start = 2010 
## End = 2019 
## Frequency = 1 
##  [1]  1  2  3  4  5  6  7  8  9 10
Frequência frequency
Anual 1
Semestral 2
Quadrimestral 3
Trimestral 4
Bimestral 6
Mensal 12
Semanal 365/7 ou 365.2425/7
Diária 365 ou 365.2425
ts(1:10, start = 2010, frequency = 1) # 10 observações anuais iniciando em 2010
## Time Series:
## Start = 2010 
## End = 2019 
## Frequency = 1 
##  [1]  1  2  3  4  5  6  7  8  9 10
ts(1:10, start = c(2010,2), frequency = 2) # 2º semestre de 2010
## Time Series:
## Start = c(2010, 2) 
## End = c(2015, 1) 
## Frequency = 2 
##  [1]  1  2  3  4  5  6  7  8  9 10
ts(1:10, start = c(2010,2), frequency = 3) # 2º quadrimestre de 2010
## Time Series:
## Start = c(2010, 2) 
## End = c(2013, 2) 
## Frequency = 3 
##  [1]  1  2  3  4  5  6  7  8  9 10
(z1 <- ts(1:10, start = c(2010, 2), frequency = 4)) # 2º trimestre de 2010
##      Qtr1 Qtr2 Qtr3 Qtr4
## 2010         1    2    3
## 2011    4    5    6    7
## 2012    8    9   10
ts(1:10, start = c(2010, 2), frequency = 6) # 2º bimestre de 2010
## Time Series:
## Start = c(2010, 2) 
## End = c(2011, 5) 
## Frequency = 6 
##  [1]  1  2  3  4  5  6  7  8  9 10
ts(1:10, start = c(2010, 2), frequency = 12) # 2º mês (fev) de 2010
##      Feb Mar Apr May Jun Jul Aug Sep Oct Nov
## 2010   1   2   3   4   5   6   7   8   9  10
ts(1:10, start = c(2010, 2), frequency = 365/7) # 2ª semana de 2010
## Time Series:
## Start = 2010.01917808219 
## End = 2010.19178082192 
## Frequency = 52.1428571428571 
##  [1]  1  2  3  4  5  6  7  8  9 10

Dados diários são menos elegantes via ts().

inds <- seq(as.Date('2010-02-01'), by = 'day', length.out = 10) # 01/fev/2010 
myts <- ts(1:10,
           start = c(2010, as.numeric(base::format(inds[1], "%j"))), # 32º dia do ano
           frequency = 365)
myts
## Time Series:
## Start = c(2010, 32) 
## End = c(2010, 41) 
## Frequency = 365 
##  [1]  1  2  3  4  5  6  7  8  9 10

Exercício 12.4 Considere dados temporais diários.
a. Leia a discussão https://stackoverflow.com/questions/33128865/starting-a-daily-time-series-in-r, em especial a resposta de Gavin Simpson.
b. Leia o artigo https://sciencenotes.org/how-to-convert-days-to-years/ de Anne Helmenstine.

Séries multivariadas também podem ser geradas via ts().

set.seed(99)
zm1 <- ts(matrix(rnorm(300), 100, 3), start = c(2015, 1), frequency = 12)
class(zm1)
## [1] "mts"    "ts"     "matrix" "array"
is.mts(zm1) # é uma série temporal multivariada?
## [1] TRUE
head(zm1)
##            Series 1   Series 2   Series 3
## Jan 2015  0.2139625 -1.5250694 -0.8078470
## Feb 2015  0.4796581 -0.5009917 -0.2181119
## Mar 2015  0.0878287 -1.2131812 -2.1144011
## Apr 2015  0.4438585 -0.6302768  0.4284235
## May 2015 -0.3628379 -1.4474855 -1.1417398
## Jun 2015  0.1226740 -0.1669084 -0.8368590

12.5.2 zoo - Z’s Ordered Observations

O pacote zoo (Zeileis and Grothendieck 2005b) fornece infraestrutura para séries regular e irregulamente espaçadas, desenvolvida para ser tão consistente quanto o possível com ts(). De acordo com (Zeileis and Grothendieck 2005a, 6), a classe zooreg preenche a lacuna entre séries irregulares e estritamente regulares. Objetos desta classe herdam da classe zoo, mas possuem um atributo adicional frequency, no qual a frequência da série é armazenada. Desta forma podem ser empregados para representar séries estritamente e fracamente regulares. Para criar um objeto zooreg podem-se utilizar os comandos zoo() ou zooreg(), sendo que o comando zooreg() usa basicamente os mesmos argumentos de ts().

zoo(x, order.by, frequency)
zooreg(data, start, end, frequency, deltat, ts.eps, order.by)

library(zoo)
zooreg(1:10, start = 2010, frequency = 1) # 10 observações anuais iniciando em 2010
## 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 
##    1    2    3    4    5    6    7    8    9   10
zooreg(1:10, start = c(2010,2), frequency = 2) # 2º semestre de 2010
## 2010(2) 2011(1) 2011(2) 2012(1) 2012(2) 2013(1) 2013(2) 2014(1) 2014(2) 2015(1) 
##       1       2       3       4       5       6       7       8       9      10
zooreg(1:10, start = c(2010,2), frequency = 3) # 2º quadrimestre de 2010
## 2010(2) 2010(3) 2011(1) 2011(2) 2011(3) 2012(1) 2012(2) 2012(3) 2013(1) 2013(2) 
##       1       2       3       4       5       6       7       8       9      10
(z2 <- zooreg(1:10, start = c(2010, 2), frequency = 4)) # 2º trimestre de 2010
## 2010 Q2 2010 Q3 2010 Q4 2011 Q1 2011 Q2 2011 Q3 2011 Q4 2012 Q1 2012 Q2 2012 Q3 
##       1       2       3       4       5       6       7       8       9      10
(z3 <- zoo(1:10, seq(2010+1/4, by = 1/4, length.out = 10), frequency = 4)) # equivalente à linha anterior
## 2010 Q2 2010 Q3 2010 Q4 2011 Q1 2011 Q2 2011 Q3 2011 Q4 2012 Q1 2012 Q2 2012 Q3 
##       1       2       3       4       5       6       7       8       9      10
all.equal(z2,z3)
## [1] TRUE
zooreg(1:10, start = c(2010, 2), frequency = 6) # 2º bimestre de 2010
## 2010(2) 2010(3) 2010(4) 2010(5) 2010(6) 2011(1) 2011(2) 2011(3) 2011(4) 2011(5) 
##       1       2       3       4       5       6       7       8       9      10
zooreg(1:10, start = c(2010, 2), frequency = 12) # 2º mês (fev) de 2010
## Feb 2010 Mar 2010 Apr 2010 May 2010 Jun 2010 Jul 2010 Aug 2010 Sep 2010 Oct 2010 Nov 2010 
##        1        2        3        4        5        6        7        8        9       10
zooreg(1:10, start = c(2010, 2), frequency = 365/7) # 2ª semana de 2010
##  2010(2)  2010(3)  2010(4)  2010(5)  2010(6)  2010(7)  2010(8)  2010(9) 2010(10) 2010(11) 
##        1        2        3        4        5        6        7        8        9       10

Exercício 12.5 Considerando o exemplo acima de equivalência entre zooreg() e zoo() no trimestre, replique as séries utilizando a função zoo().

A função zoo::zoo() facilita a atribuição de séries temporais através do argumento order.by. Esta abordagem é aplicada também em xts::as.xts() (veja a seguir).

set.seed(42)
x.date <- as.POSIXct(paste0("2003-", rep(1:4, 4:1), "-", 
                            sample(1:28, 10, replace = TRUE)))
(x <- zoo(matrix(rnorm(20), ncol = 2), x.date))
##                                 
## 2003-01-01  1.5548955  0.9657529
## 2003-01-05 -0.6575028  0.4822047
## 2003-01-17  0.5802063  0.8817912
## 2003-01-25 -1.1876414 -0.8145709
## 2003-02-04 -1.0861326 -0.1616986
## 2003-02-10  0.1518129  0.2839578
## 2003-02-18  1.6133728  1.9355718
## 2003-03-17  1.3149588  0.3584021
## 2003-03-26  0.0356312  1.7232308
## 2003-04-15  0.9781675  0.3024309

Exemplo 12.2 Considere o conjunto de dados de casos semanais de varicela na Hungria17. Consiste em uma matriz de séries temporais por condado dos casos relatados entre 2005 e 2015.

Pode-se verificar a regularidade das séries via zoo::is.regular(), na qual o argumento strict verifica a regularidade estrita. Note que séries geradas via ts() sempre indicam regularidade estrita, mesmo quando retiramos um ou mais pontos.

# gerada com ts()
zoo::is.regular(z1)
## [1] TRUE
zoo::is.regular(z1[-3], strict = TRUE)
## [1] TRUE
# gerada com zooreg()
zoo::is.regular(z2)
## [1] TRUE
zoo::is.regular(z2[-3], strict = TRUE)
## [1] FALSE
# gerada com zoo()
zoo::is.regular(z3)
## [1] TRUE
zoo::is.regular(z3[-3], strict = TRUE)
## [1] FALSE

Pode-se consultar a frequência de uma série temporal via stats::frequency(). Note que as séries geradas via ts() sofrem alteração quando retiram-se observações.

# gerada com ts()
frequency(z1)
## [1] 4
frequency(z1[-3])
## [1] 1
# gerada com zooreg()
frequency(z2)
## [1] 4
frequency(z2[-3])
## [1] 4
# gerada com zoo()
frequency(z3)
## [1] 4
frequency(z3[-3])
## [1] 4

A função zoo::coredata() permite extrair e substituir dados de objetos da classe zoo.

class(z2)
## [1] "zooreg" "zoo"
coredata(z2)
##  [1]  1  2  3  4  5  6  7  8  9 10
class(coredata(z2))
## [1] "integer"
coredata(z2)[5] <- 99
z2
## 2010 Q2 2010 Q3 2010 Q4 2011 Q1 2011 Q2 2011 Q3 2011 Q4 2012 Q1 2012 Q2 2012 Q3 
##       1       2       3       4      99       6       7       8       9      10

A função zoo::index() permite extrair e substituir o índice de objetos da classe zoo.

zoo::index(z2)
##  [1] "2010 Q2" "2010 Q3" "2010 Q4" "2011 Q1" "2011 Q2" "2011 Q3" "2011 Q4" "2012 Q1" "2012 Q2"
## [10] "2012 Q3"

As funções stats::start() e stats::end() fornecem o início e o fim do vetor de índice/tempo.

stats::start(z2)
## [1] "2010 Q2"
stats::end(z2)
## [1] "2012 Q3"

O tratamento de NA pode ser feito com funções específicas.

z2[6] <- NA
na.omit(z2)         # omite observações NA
## 2010 Q2 2010 Q3 2010 Q4 2011 Q1 2011 Q2 2011 Q4 2012 Q1 2012 Q2 2012 Q3 
##       1       2       3       4      99       7       8       9      10
na.contiguous(z2)   # apresenta a série até o primeiro NA
## 2010 Q2 2010 Q3 2010 Q4 2011 Q1 2011 Q2 
##       1       2       3       4      99
zoo::na.approx(z2)  # substitui NA por valores interpolados linearmente, (99+7)/2=53
## 2010 Q2 2010 Q3 2010 Q4 2011 Q1 2011 Q2 2011 Q3 2011 Q4 2012 Q1 2012 Q2 2012 Q3 
##       1       2       3       4      99      53       7       8       9      10
forecast::na.interp(z2) # substitui NA por valores interpolados linearmente
## Time Series:
## Start = 1 
## End = 10 
## Frequency = 1 
##  [1]  1  2  3  4 99 53  7  8  9 10
zoo::na.spline(z2)  # substitui NA por valores interpolados via spline, veja ?spline
##  2010 Q2  2010 Q3  2010 Q4  2011 Q1  2011 Q2  2011 Q3  2011 Q4  2012 Q1  2012 Q2  2012 Q3 
##  1.00000  2.00000  3.00000  4.00000 99.00000 76.13273  7.00000  8.00000  9.00000 10.00000
zoo::na.locf(z2)    # substitui cada NA com o mais recente não NA
## 2010 Q2 2010 Q3 2010 Q4 2011 Q1 2011 Q2 2011 Q3 2011 Q4 2012 Q1 2012 Q2 2012 Q3 
##       1       2       3       4      99      99       7       8       9      10

Séries multivariadas com zooreg().

set.seed(99)
zm2 <- zooreg(matrix(rnorm(300), 100, 3), start = c(2015, 1), frequency = 12)
head(zm2) # zooreg()
##                                          
## Jan 2015  0.2139625 -1.5250694 -0.8078470
## Feb 2015  0.4796581 -0.5009917 -0.2181119
## Mar 2015  0.0878287 -1.2131812 -2.1144011
## Apr 2015  0.4438585 -0.6302768  0.4284235
## May 2015 -0.3628379 -1.4474855 -1.1417398
## Jun 2015  0.1226740 -0.1669084 -0.8368590
head(zm1) # ts()
##            Series 1   Series 2   Series 3
## Jan 2015  0.2139625 -1.5250694 -0.8078470
## Feb 2015  0.4796581 -0.5009917 -0.2181119
## Mar 2015  0.0878287 -1.2131812 -2.1144011
## Apr 2015  0.4438585 -0.6302768  0.4284235
## May 2015 -0.3628379 -1.4474855 -1.1417398
## Jun 2015  0.1226740 -0.1669084 -0.8368590

12.5.3 xts - eXtensible Time Series

O pacote xts (Ryan and Ulrich 2024) é baseado em zoo e fornece tratamento uniforme das diferentes classes de dados temporais do R. De acordo com o xts FAQ, xts estende o zoo e tem como principal benefício a compatibilidade com outros pacotes que usam diferentes classes de séries temporais (timeSeries, zoo, etc).

library(xts)
zm3 <- as.xts(zm2)
class(zm3)
## [1] "xts" "zoo"

Assim como em zoo::zoo(), a função xts::as.xts() facilita a atribuição de séries temporais através do argumento order.by. Ao contrário da função zoo::zoo(), xts::as.xts() só funciona com vetores.

set.seed(42)
x.date <- as.POSIXct(paste("2003-", rep(1:4, 4:1), "-", 
                           sample(1:28, 10, replace = TRUE), sep = ""))
x <- xts::as.xts(rnorm(10), x.date)
x
##                  [,1]
## 2003-01-01  1.5548955
## 2003-01-05 -0.6575028
## 2003-01-17  0.5802063
## 2003-01-25 -1.1876414
## 2003-02-04 -1.0861326
## 2003-02-10  0.1518129
## 2003-02-18  1.6133728
## 2003-03-17  1.3149588
## 2003-03-26  0.0356312
## 2003-04-15  0.9781675

12.5.4 tsibble - Tidy Temporal Data Frames and Tools

O pacote tsibble (E. Wang, Cook, and Hyndman 2020a) estende o tidyverse (Wickham et al. 2019) para dados temporais. Construído sobre o tibble, um tsibble (ou tbl_ts) é um objeto orientado a dados e modelo.

library(tsibble)
zm4 <- as_tsibble(zm1) # não funciona com `zoo` e `xts`
class(zm4)
## [1] "tbl_ts"     "tbl_df"     "tbl"        "data.frame"

Referências

Ryan, Jeffrey A., and Joshua M. Ulrich. 2024. Xts: eXtensible Time Series. https://CRAN.R-project.org/package=xts.
———. 2020a. “A New Tidy Data Structure to Support Exploration and Modeling of Temporal Data.” Journal of Computational and Graphical Statistics 29 (3): 466–78. https://doi.org/10.1080/10618600.2019.1695624.
Wickham, Hadley, Mara Averick, Jennifer Bryan, Winston Chang, Lucy D’Agostino McGowan, Romain François, Garrett Grolemund, et al. 2019. “Welcome to the tidyverse.” Journal of Open Source Software 4 (43): 1686. https://doi.org/10.21105/joss.01686.
Zeileis, Achim, and Gabor Grothendieck. 2005a. “Zoo: An S3 Class and Methods for Indexed Totally Ordered Observations.” https://cran.r-project.org/web/packages/zoo/vignettes/zoo.pdf.
———. 2005b. “Zoo: S3 Infrastructure for Regular and Irregular Time Series.” Journal of Statistical Software 14 (6): 1–27. https://doi.org/10.18637/jss.v014.i06.