SESIÓN 1. Introducción a Series de Tiempo en R

Autor/a

Gerson Rivera

Fecha de publicación

14 agosto 2024

Aplicación: Serie de tiempo 1

Creamos un conjunto de datos para practicar

Creamos una base que contenga 50 datos, provenientes de una distribución uniforme, cuyos valores son aleatorios entre 10 y 45

mydata = runif(n = 50, min = 10, max = 45)
head(mydata)
[1] 15.51144 34.33485 37.63882 36.01970 16.02981 35.92548
#View(mydata)
# Gráfico de dispersión puesto que no se ha definido la serie
plot(mydata)

Convertimos los datos a serie de tiempo

Para ese proceso utilizamos la estructura ts que implica times series

mytimeseries = ts(data = mydata, 
                  start = 1956, frequency = 4)
mytimeseries
         Qtr1     Qtr2     Qtr3     Qtr4
1956 15.51144 34.33485 37.63882 36.01970
1957 16.02981 35.92548 41.62993 43.78909
1958 14.21455 44.77029 11.38815 18.83620
1959 15.56199 15.81687 11.04422 38.30941
1960 38.72931 16.08966 10.79594 43.74265
1961 31.59915 25.96134 19.25453 43.34408
1962 28.49006 13.16730 34.74841 20.76427
1963 12.85532 40.47657 30.84409 43.36823
1964 35.63594 35.66820 33.76620 35.34535
1965 15.15952 28.50530 20.71332 42.17498
1966 15.74870 44.63739 41.91871 11.31338
1967 42.42525 16.58311 35.13270 17.60576
1968 40.81012 13.55285                  

Diferentes formas gráficas de la serie de tiempo

  • Utilizando el comando plot:
# Veamos el gráfico de la serie
plot(mytimeseries, col="green")

  • Utilizando el comando plot.ts
plot.ts(mytimeseries,
        main = "Serie de tiempo (Uniforme)",
        ylab = "datos",
        xlab = "años",
        col = "blue"
)

  • Utilizando el comando autoplot
# Habilitar librerias
library(forecast)
Registered S3 method overwritten by 'quantmod':
  method            from
  as.zoo.data.frame zoo 
library(ggplot2)
autoplot(mytimeseries) + 
  xlab("años") +
  ylab("datos") +
  ggtitle("Serie de tiempo (Uniforme)")

  • Utilizando el comando ts\_plot
# Habilitar librerias
library(TSstudio)
library(plotly)

Attaching package: 'plotly'
The following object is masked from 'package:ggplot2':

    last_plot
The following object is masked from 'package:stats':

    filter
The following object is masked from 'package:graphics':

    layout
library(dplyr)

Attaching package: 'dplyr'
The following objects are masked from 'package:stats':

    filter, lag
The following objects are masked from 'package:base':

    intersect, setdiff, setequal, union
ts_plot(mytimeseries, line.mode = "lines+markers") %>% 
  layout(title = "Serie de tiempo creada con una distribucion Uniforme",yaxis = list(title = " "))
  • Utilizando el comando dygraph
# Habilitar librerias
library(dygraphs)  
library(dplyr)
dygraph(mytimeseries, 
        main = "Serie de tiempo (Uniforme)",
        ylab = "datos", xlab="años") %>% 
  dyRangeSelector()

Análisis exploratorio

Para realizar el análisis exploratorio aplicaremos la library forecast, la cual facilita el estudio directo de tsoutliers (valores fuera de rango en la serie de tiempo)

Identificamos de manera directa la clase de datos con la que trabajamos y estudiamos los valores fuera de rango

class(mytimeseries)
[1] "ts"
tsoutliers(mytimeseries)
$index
integer(0)

$replacements
numeric(0)

Identificamos la estructura interna de los datos asociados a la serie de tiempo

time(mytimeseries)
        Qtr1    Qtr2    Qtr3    Qtr4
1956 1956.00 1956.25 1956.50 1956.75
1957 1957.00 1957.25 1957.50 1957.75
1958 1958.00 1958.25 1958.50 1958.75
1959 1959.00 1959.25 1959.50 1959.75
1960 1960.00 1960.25 1960.50 1960.75
1961 1961.00 1961.25 1961.50 1961.75
1962 1962.00 1962.25 1962.50 1962.75
1963 1963.00 1963.25 1963.50 1963.75
1964 1964.00 1964.25 1964.50 1964.75
1965 1965.00 1965.25 1965.50 1965.75
1966 1966.00 1966.25 1966.50 1966.75
1967 1967.00 1967.25 1967.50 1967.75
1968 1968.00 1968.25                

Estructuramos las fechas de la serie de tiempo

mytimeseries = ts(data = mydata, 
                  start = c(1956,3), frequency = 4)
#mytimeseries

Aplicación: Serie de tiempo 2

Serie de tiempo nottem

Analizamos el gráfico de la serie nottem, cuya descripción es:

  • Temperaturas mensuales promedio en Nottingham, en el periodo 1920–1939. Es un objeto de la clase serie temporal que contiene la temperatura media del aire en el castillo de Nottingham en grados Fahrenheit, durante 20 años.
# Gráfica 1
plot(nottem, col="red")

# Gráfica 2
plot.ts(nottem,
        main = "Gráfica de Temperaturas de Nottingham",
        ylab = "Temperaturas",
        xlab = "Años",
        col = "blue"
        )

# Gráfica 3
autoplot(nottem)

# Gráfica 4
autoplot(nottem) + 
  xlab("Tiempos")+
  ylab("Temperaturas")+
  ggtitle("Autoplot of Nottingham temperature data")

#View(nottem)

# No existen valores perdidos
summary(nottem)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  31.30   41.55   47.35   49.04   57.00   66.50 

Aplicación: Serie de tiempo 3

Serie de tiempo airquality

Analizamos el gráfico de la serie airquality, cuya descripción es:

  • Mediciones de la calidad del aire de Nueva York. Las mediciones son diarias, el cual contiene 153 observaciones sobre 6 variables.

Lecturas diarias de los siguientes valores de calidad del aire del 1 de mayo de 1973 (martes) al 30 de septiembre de 1973.

  • Ozono: Ozono medio en partes por billón de 1300 a 1500 horas en Roosevelt Island
  • Solar.R: Radiación solar en Langleys en la banda de frecuencia 4000–7700 Angstroms de 08:00 a 12:00 horas en Central Park
  • Viento: Velocidad promedio del viento en millas por hora a las 07:00 y 10:00 horas en el Aeropuerto LaGuardia
  • Temp: Temperatura máxima diaria en grados Fahrenheit en el Aeropuerto La Guardia
  • Mes: Valor numerico, comprendido entre 1 y 12
  • Día: Valor numerico, comprendido entre 1 y 31

Análisis de Datos faltantes y outliers

head(airquality)
  Ozone Solar.R Wind Temp Month Day
1    41     190  7.4   67     5   1
2    36     118  8.0   72     5   2
3    12     149 12.6   74     5   3
4    18     313 11.5   62     5   4
5    NA      NA 14.3   56     5   5
6    28      NA 14.9   66     5   6
plot(airquality)

require(graphics)
pairs(airquality, panel = panel.smooth, main = "Datos de calidad de aire")

summary(airquality)
     Ozone           Solar.R           Wind             Temp      
 Min.   :  1.00   Min.   :  7.0   Min.   : 1.700   Min.   :56.00  
 1st Qu.: 18.00   1st Qu.:115.8   1st Qu.: 7.400   1st Qu.:72.00  
 Median : 31.50   Median :205.0   Median : 9.700   Median :79.00  
 Mean   : 42.13   Mean   :185.9   Mean   : 9.958   Mean   :77.88  
 3rd Qu.: 63.25   3rd Qu.:258.8   3rd Qu.:11.500   3rd Qu.:85.00  
 Max.   :168.00   Max.   :334.0   Max.   :20.700   Max.   :97.00  
 NA's   :37       NA's   :7                                       
     Month            Day      
 Min.   :5.000   Min.   : 1.0  
 1st Qu.:6.000   1st Qu.: 8.0  
 Median :7.000   Median :16.0  
 Mean   :6.993   Mean   :15.8  
 3rd Qu.:8.000   3rd Qu.:23.0  
 Max.   :9.000   Max.   :31.0  
                               

Convertir a serie de tiempo

myts = ts(airquality$Ozone)
myts
Time Series:
Start = 1 
End = 153 
Frequency = 1 
  [1]  41  36  12  18  NA  28  23  19   8  NA   7  16  11  14  18  14  34   6
 [19]  30  11   1  11   4  32  NA  NA  NA  23  45 115  37  NA  NA  NA  NA  NA
 [37]  NA  29  NA  71  39  NA  NA  23  NA  NA  21  37  20  12  13  NA  NA  NA
 [55]  NA  NA  NA  NA  NA  NA  NA 135  49  32  NA  64  40  77  97  97  85  NA
 [73]  10  27  NA   7  48  35  61  79  63  16  NA  NA  80 108  20  52  82  50
 [91]  64  59  39   9  16  78  35  66 122  89 110  NA  NA  44  28  65  NA  22
[109]  59  23  31  44  21   9  NA  45 168  73  NA  76 118  84  85  96  78  73
[127]  91  47  32  20  23  21  24  44  21  28   9  13  46  18  13  24  16  13
[145]  23  36   7  14  30  NA  14  18  20

Comprobar si hay NAs y outliers

summary(myts)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
   1.00   18.00   31.50   42.13   63.25  168.00      37 
plot(myts)

Usando zoo para localizar y rellenar valores faltantes

Activamos la libreria zoo y realizamos sustituciones posterior a determinar cual es la mejor perspectiva a retomar, de tal manera que dicha sustitución no altere la confiabilidad de los datos y a la vez garantice la representatividad de los mismos.

La función LOCF, copia la última observación antes del NA (not available o no disponible).

LOCF: last observation carried forward

myts.NAlocf = na.locf(myts)
#myts.NAlocf

En este caso la sustitución se hace por un valor específico, que se considere representativo.

myts.NAfill = na.fill(myts, 33)
#myts.NAfill

Detección automática de outliers con la librería forecast

mean(myts,na.rm = TRUE)
[1] 42.12931
myts[c(42.12931)]
[1] NA

En este caso la sustitución se hace por la media de la serie, siempre que se considere representativa.

myts.NAmean = na.fill(myts, 42.12931)
#myts.NAmean

Finalmente hacemos un exploratorio con forecast

myts1 = tsoutliers(myts)
myts1
$index
[1]  30 117

$replacements
[1] 41 59

Este método realiza un interpolación y sustituye el valor no disponible.

myts.NAinterp = na.interp(myts)
#myts.NAinterp

Limpiando NAs y outliers con tsclean del paquete forecast

mytsclean = tsclean(myts)
#mytsclean

Resumen de etapas

summary(myts)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
   1.00   18.00   31.50   42.13   63.25  168.00      37 
summary(myts.NAlocf)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   16.00   30.00   39.78   52.00  168.00 
summary(myts.NAfill)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   21.00   33.00   39.92   46.00  168.00 
summary(myts.NAmean)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    1.0    21.0    42.0    42.1    46.0   168.0 
summary(myts.NAinterp)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   20.00   33.57   43.29   63.00  168.00 
summary(mytsclean)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   20.00   33.57   42.09   59.00  135.00 
plot(myts)

plot(myts.NAlocf)

plot(myts.NAfill)

plot(myts.NAmean)

plot(myts.NAinterp)

plot(mytsclean)