Una serie temporal es una sucesión de observaciones de una variable tomadas en distintos momentos del tiempo. Conforman, por lo tanto, distribuciones bidimensionales en las que una de las variables es el tiempo y la otra los “casos” o sujetos, los diferentes valores de una variable medidos a lo largo de un intervalo temporal.
Estas series son muy importantes para múltiples disciplinas, entre ellas la Geografía. Ejemplos:
Demografía: evolución de la población, tasas de mortalidad infantil etc.
Medioambiente: evolución de los contaminantes medidos en una ciudad, lluvia recogida, temperatura media, residuos tóxicos en un río etc.
La forma más usual de presentar estas distribuciones es una tabla con dos columnas:
La variable tiempo (“variable independiente”) se representa como \(t_i\).
La variable objeto de estudio (“variable dependiente”) se representa como \(y_i\).
Una característica que distingue las series temporales es su orden cronológico. Esta circunstancia determina, además, que los datos de una serie temporal experimenten autocorrelación. Por ejemplo, la tasa de paro de un trimestre suele depender de la tasa del trimestre anterior.
Los objetivos del análisis de una serie temporal son los siguientes:
Comprender cómo ha evolucionado un proceso en el pasado (y de paso, los mecanismos que regulan su comportamiento en el tiempo).
Preveer valores futuros.
Para la realización de las actividades de este tema el script puede descargarse aquí
R trabaja con objetos pertenecientes a la clase ts
(time
series). La función ts()
convierte un objeto (vector o
dataframe) en una serie temporal; si no informamos de otra cosa, el
primer caso del objeto corresponderá a \(t_1\), el segundo a \(t_2\) etc… La construcción de objetos de la
clase ts
requiere que los datos de partida estén
distribuidos regularmente en la escala temporal utilizada.
La práctica se inicia importando los datos, que está en formato excel, desde la página web “https://personales.unican.es/rasillad/docencia/G14/TEMA_4”. Primero debe activarse el paquete readxl para acceder a los datos en formato excel.
#if(!require("readxl")) install.packages("readxl")
library(readxl)
A continuación se establece el vínculo con el servidor de los datos,
que importará el fichero en la carpeta que esté activada por defecto con
el nombre que deseemos (argumento destfile
)
<-"https://personales.unican.es/rasillad/docencia/G14/TEMA_4/series_temporales.xlsx"
urldownload.file(url,
destfile = "ejemplos_series_temporales.xlsx",
mod="wb")
La primera serie aparece en la hoja de cálculo “ejemplo1”.
<- read_excel("ejemplos_series_temporales.xlsx",
ejemplo1 sheet = "ejemplo1")
ejemplo1
Consiste en la duración en años del reinado de una serie de monarcas
en sucesión consecutiva. El procedimiento se inicia transformando el
vector original en una serie temporal (objeto ts
).
<- ts(ejemplo1$reyes)
reyes.ts reyes.ts
Además, podemos comprobar esa sucesión representando gráficamente
esta serie temporal con la función plot.ts
,
plot.ts(reyes.ts,
col = 'darkgreen',
lwd = 1.5)
La segunda serie es algo más compleja, ya que contiene el número mensual de nacimientos en España desde enero de 1946.
<- read_excel("ejemplo.xlsx",
nacimientos sheet = "ejemplo2")
head(nacimientos)
En este caso, se puede incorporar información sobre el periodo temporal del que existen datos con dos argumentos:
frecuency
: una serie mensual
corresponde a una frecuencia de 12 meses.
start
: fecha (año y mes) de
comienzo de la serie.
<- ts(nacimientos,
nacimientos.ts frequency=12,
start=c(1946,1))
R dispone de diferentes argumentos para caracterizar cualquier serie temporal:
class(nacimientos.ts) # Confirma el tipo de serie ts
start(nacimientos.ts) # Comienzo de la serie
end(nacimientos.ts) # Final de la serie
frequency(nacimientos.ts) # Periodicidad de la serie
time(nacimientos.ts) # Vector con los intervalos temporales
cycle(nacimientos.ts) # Unidad de tiempo a la que pertenece cada observación
print(nacimientos.ts)
Finalmente, se puede representar gráficamente.
plot.ts(nacimientos.ts,
col = 'brown',
lwd = 1.5,
xlab = "Años")
# setwd("")
<-"https://personales.unican.es/rasillad/docencia/G14/TEMA_4/series_temporales_2.xlsx"
urldownload.file(url,
destfile = "series_temporales_2.xlsx",
mod="wb")
temperatura
como serie temporal
(hoja de cálculo temperatura
) y represéntala
gráficamente.<- read_excel("series_temporales_2.xlsx",
df_temperatura sheet = "Temperatura")
<- min(df_temperatura$año)
min_temperatura <- ts(df_temperatura$tem,
temperatura_ts frequency=1,
start=c(min(df_temperatura$año),1))
plot.ts(temperatura_ts,
col = 'brown',
lwd = 1.5,
xlab = "Años",
ylab = "ºC",
las = 1,
main = "Temperatura media del planeta",
ylim = c(13, 16))
<- read_excel("series_temporales_2.xlsx",
df_incendios sheet = "Incendios")
<- min(df_incendios$AÑO)
min_incendios
<- ts(df_incendios$SUP_ARB,
sup_arb_ts frequency=1,
start=c(min(df_incendios$AÑO),1))
<- ts(df_incendios$SUP_NO_ARB,
sup_no_arb_ts frequency=1,
start=c(min(df_incendios$AÑO),1))
<- ts(df_incendios$INCENDIOS,
incendios_ts frequency=1,
start=c(min(df_incendios$AÑO),1))
plot.ts(sup_arb_ts,
col = 'green',
lwd = 1.5,
xlab = "Años")
plot.ts(sup_no_arb_ts,
col = 'darkgreen',
lwd = 1.5)
ts.plot(sup_arb_ts,
sup_no_arb_ts,gpars = list(col = c("black", "red")),
xlab = "Años",
ylab = "Hectáreas",
main = "Evolución de la superficie quemada")
plot.ts(incendios_ts,
col = 'darkgreen',
lwd = 1.5)
Consiste en separar e identificar los diferentes componentes de una serie temporal. Los más habituales son:
Tendencia: comportamiento a largo plazo de la serie. Puede ser creciente (positiva) o decreciente (negativa), dependiendo de si exhibe una evolución ascendente o descendente. Una serie así se considera organizada y no estacionaria. Si no muestra ninguna tendencia, se considera que es estacionaria y no organizada.
Componente cíclica: cualquier fluctuación que sigue un comportamiento periódico alrededor de la tendencia.
Figura 1. Componente cíclica
Figura 2. Componente estacional
Figura 3. Componente aleatoria
De tal manera que una serie temporal puede encuadrarse en dos modelos según cómo se combinen estos componentes:
\(y = T + C + S + I\): modelo
aditivo que incluye
Tendencia + Componente cíclica + Componente estacional + Componente aleatoria
.
\(y = T x C x S x I\): modelo
multiplicativo que incluye
Tendencia x Componente cíclica x Componente estacional x Componente aleatoria
.
El tratamiento de una serie temporal depende de su naturaleza.
Las series estacionarias pueden analizarse con los métodos estadísticos analizados en los temas anteriores (cálculo de estadísticos como media, desviación típica, elaboración de gráficos como histogramas etc.).
En el caso de las series no estacionarios, estos procedimientos no pueden utilizarse, ya que asumen que no hay cambios en dichas magnitudes. En este caso el procedimiento de análisis sigue varios pasos:
Determinar si una serie está organizada, cuantificar la tendencia y extraer dicha tendencia.
Determinar si una serie muestra variaciones estacionales y extraer esas variaciones de los datos originales.
En este tema, nos centramos en datos temporales denominados de baja frecuencia (series anuales, trimestrales y mensuales), y se aplicarán procedimientos estadísticos para cuantificar, si existe, la tendencia, y aislar el comportamiento estacional. Otros aspectos, especialmente los ligados al análisis de las observaciones de alta frecuencia (diarias, horarias etc), que son mucho más complejos, serán omitidos.
La tendencia es el componente más relevante de cualquier serie temporal. En función de si presenta esta componente o no, es posible diferenciar dos tipos de series temporales:
Son aquellas en las que sus propiedades estadísticas (fundamentalmente su valor medio y su dispersión) son estables, es decir, no varían con el tiempo. Si una serie temporal tiene una media constante a lo largo del tiempo, es estacionaria con respecto a la media. Si tiene varianza constante con respecto al tiempo, es estacionaria en varianza.
¿Qué tienen de bueno las series estacionarias?: como sus propiedades estadísticas son constantes, podemos estimarlas fácilmente y predecir una nueva observación.
Figura 4: serie estacionaria
Un tipo especial de serie estacionaria es la serie denominada ruido blanco. Es una serie en la que ninguna observación influye sobre las siguientes, es decir, sus valores son totalmente independientes e idénticamente distribuidos a lo largo del tiempo con media cero e igual varianza en el tiempo.
Figura 5. Ruido blanco
Son aquellas en las que su valor medio y su dispersión cambian a lo largo del tiempo, es decir, ambas propiedades pueden crecer o decrecer y no oscilan en torno a un valor constante.
De acuerdo con lo antes expuesto, las series pueden ser:
Serie aditiva: la variabilidad se mantiene en el tiempo.
Serie multiplicativa: La variabilidad cambia (aumenta o disminuye) con el tiempo.
Por lo tanto, el primer aspecto a determinar es si una series temporal tiene un comportamiento estacionario respecto a la media (es decir, si tiene tendencia) o respecto a la varianza..
Cuando analizarmos si una serie tiene un comportamiento estacionario, se analiza si la serie posee tendencia, es decir, si estká organizada. Esta tendencia consiste en un cambio a largo plazo de la media, lo que supone que la serie experimenta cierto grado de autocorrelación temporal, es decir, que el valor observado en un tiempo \(y_1\) condiciona, creciendo o decreciendo, el valor alcanzado en el tiempo \(y_2\) y sucesivamente.
Esta tendencia puede ser:
Figura 6. Tendencia lineal
Figura 7. Tendencia estocástica
En este apartado se revisan una serie de pruebas para determinar si una serie es estacionaria, es decir, si está organizada, o sea, si tiene tendencia o no. Partiremos de las pruebas más sencillas hasta las más complejas
Ejemplo manual de aplicación de la prueba de von Newmann
<- c(2,4,5,7,9)
data <- ts(data) data.ts
Figura 8
<- sum((diff(data.ts))^2)
numerador <- length(data.ts)-1
denominador
<- numerador/denominador
rho <- var(data.ts)*(length(data.ts)-1)/length(data.ts) # Varianza var
Cálculo del parámetro K. Si el resultado es próximo a 2 la serie sería aleatoria, en caso contrario estaría organizada (el caso presentado).
<- rho/var
K K
rm(denominador, K, numerador, rho, var, data, data.ts)
La prueba de Bartels es una versión mejorada de la de von Neumann, que utiliza los rangos (número de orden) de cada componente de una serie temporal. Su objetivo:
\(H_0\) (hipótesis nula): los
elementos siguen un orden aleatorio (sin tendencia en los datos).
Corresponde a un p-value
mayor que algún
nivel de significación (la opción más común α = 0.05).
\(H_A\) (hipótesis alternativa):
los elementos están organizados (hay una tendencia estadísticamente
significativa, que podría ser positiva o negativa) si el
p-value
es menor que α = 0.05.
if (!require("trend")) install.packages("trend")
library(trend)
bartels.test(reyes.ts)
También se puede someter una serie temporal a un análisis de
correlación entre los valores de la variable (\(y_1\)) y el tiempo (\(t_1\)). Se recomienda el uso del
coeficiente de correlación de Spearman, ya que las series temporales no
suelen tener una distribución normal. Si la relación entre ambas
variables es signficativa (p-value
) se considera que existe
una tendencia significativa
cor.test(reyes.ts, # Variable y: la serie temporal a analizar
time(reyes.ts), # Variable x: el periodo temporal a analizar
method = "spearman")
Es una prueba no paramétrica, lo que significa que no se realiza ninguna suposición subyacente sobre la normalidad de los datos. Las hipótesis para la prueba son las siguientes:
\(H_0\) (hipótesis nula): no hay
una tendencia en los datos. Corresponde a un p-value
mayor que algún nivel de significación (la opción más
común α = 0.05).
\(H_A\) (hipótesis alternativa):
hay una tendencia estadísticamente significativa (que podría ser
positiva o negativa) si el p-value
es
menor que α = 0.05.
Para realizar la prueba, se usa la función MannKendall()
del paquete Kendall, a través de la siguiente
sintaxis:
if(!require("Kendall")) install.packages("Kendall")
library(Kendall)
<- MannKendall(reyes.ts)
mk.reyes.ts summary(mk.reyes.ts)
El estadístico de prueba es 0.301 y el p-value
correspondiente es 0.027486 . Debido a que este p-value
es
menor que 0.05, rechazaremos la hipótesis nula de la prueba y
concluiremos que existe una tendencia en los datos.
temperatura
, SUP_ARB
, SUP_NO_ARB
e INCENDIOS
y compara la significación de las tendencias
obtenidas con las calculadas aplicando la correlación de Spearman.bartels.test(temperatura.ts)
MannKendall(temperatura.ts)
cor.test(temperatura.ts,
time(temperatura.ts),
method = "spearman")
bartels.test(sup_arb_ts)
MannKendall(sup_arb_ts)
cor.test(sup_arb_ts,
time(sup_arb_ts),
method = "spearman")
bartels.test(sup_no_arb_ts)
MannKendall(sup_no_arb_ts)
cor.test(sup_no_arb_ts,
time(sup_no_arb_ts),
method = "spearman")
bartels.test(incendios_ts)
MannKendall(incendios_ts)
cor.test(incendios_ts,
time(incendios_ts),
method = "spearman")
Para la obtención de la tendencia lineal mediante un modelo de regresión, debe considerarse variable dependente a \(y_n\) (en el ejemplo la duración del reinado en años) y variable independiente al tiempo \(t_n\).
<- lm(reyes.ts~time(reyes.ts)) modelo.regresion.reyes.ts
La pendiente (término a) equivale a la tendencia (valor/unidad de tiempo). Los valores ajustados (predichos) corresponden a la evolución a largo plazo de la tendencia (línea recta).
$coefficients
modelo.regresion.reyes.ts$fitted.values modelo.regresion.reyes.ts
Esta tendencia a largo plazo puede representarse gráficamente
ts.plot(reyes.ts,
xlab="Periodo temporal ",
ylab="Duración del reinado",
main= "Evolución del reinado")
points(reyes.ts)
abline(modelo.regresion.reyes.ts) # Dibuja la recta con la tendencia
Los resíduos son los valores que resultan una vez eliminada la tendencia. Podemos representarlos gráficamente también
ts.plot(modelo.regresion.reyes.ts$residuals)
Este procedimiento se utiliza para descubrir tendencias en series temporales, pero es más resistente a valores atípicos, y no es paramétrico, ya que no se basa en ninguna distribución de probabilidad en particular. El método, descrito por primera vez por Theil y luego ampliado por Sen (1968), se denomina estimador de Thiel-Sen. Es una alternativa a la regresión por mínimos cuadrados, pero mientras este último método usa la media para estimar la pendiente, Sen usa la mediana.
El cálculo de la pendiente de la recta se realiza mediante dos pasos:
Calcular pendientes para todos los pares de puntos de tiempo ordenados.
Encuentra la mediana de todas las pendientes obtenidas en el procedimiento anterior.
Este procedimiento está incorporado en el paquete trend y su sintaxis es la siguiente:
sens.slope(x, conf.level = 0.95)
Donde:
x = vector numérico o un objeto de serie temporal de clase “ts”,
conf.level = nivel de significancia numérica .
if(!require("trend")) install.packages("trend")
library(trend)
sens.slope(reyes.ts,conf.level = 0.95)
Al igual que en los otros procedimientos, se puede solicitar la
impresión en pantalla del valor de la tendencia ($estimate
)
y el p-value
de esa tendencia.
sens.slope(reyes.ts)$estimate
sens.slope(reyes.ts)$p.value
Sin embargo, el paquete trend no genera el término b (origen de la línea de regresión). Para obtenerlo necesitamos acudir a otro paquete, denominado zyp.
if (!require("zyp")) install.packages("zyp")
library(zyp)
Para que este procedimiento funcione, es necesario crear un vector con las unidades de tiempo.
<- seq(1, 42, length=42) # Creación de una variable denominada tiempo
tiempo zyp.sen(reyes.ts~tiempo) # Cálculo de la pendiente según el método de Sen
Al igual que en el caso anterior, se puede requerir los términos a y b de la línea de regresión y los resíduos.
zyp.sen(reyes.ts~tiempo)$coefficients # Términos a y b
zyp.sen(reyes.ts~tiempo)$residuals # Los resíduos son los valores que resultan una vez eliminada la tendencia
ts.plot(zyp.sen(reyes.ts~tiempo)$residuals)
Finalmente, se puede calcular una tendencia lineal con eliminación previa de la autocorrelación temporal (prewhitened linear trend)
zyp.trend.vector(reyes.ts)
Si se desea obtener el valor de la tendencia (linear
)
mediante la expresión zyp.trend.vector(reyes.ts)$linear
se
obtiene un mensaje de error. Este error ocurre cuando se intenta acceder
a un elemento de un vector atómico. Un “vector atómico” es cualquier
objeto de datos unidimensional creado mediante las funciones c() o
vector() en R. En su lugar, deben usarse corchetes dobles [[]] o la
función getElement().
zyp.trend.vector(reyes.ts)[['linear']]
Desafío. Compara la tendencia obtenida aplicando un
procedimiento de regresión lineal y el método de Sen a las series
temporales temperatura
, SUP_ARB
,
SUP_NO_ARB
e INCENDIOS
.
## Regresión lineal
<- lm(temperatura.ts~time(temperatura.ts))
modelo.regresion.temperatura_ts $coefficients
modelo.regresion.temperatura_ts
<- lm(sup_arb_ts~time(sup_arb_ts))
modelo.regresion.sup_arb_ts $coefficients
modelo.regresion.sup_arb_ts
<- lm(sup_no_arb_ts~time(sup_no_arb_ts))
modelo.regresion.sup_no_arb_ts $coefficients
modelo.regresion.sup_no_arb_ts
<- lm(incendios_ts~time(incendios_ts))
modelo.regresion.incendios_ts $coefficients
modelo.regresion.incendios_ts
## Método de Sen
sens.slope(temperatura.ts)$estimate
sens.slope(sup_arb_ts)$estimate
sens.slope(sup_no_arb_ts)$estimate
sens.slope(incendios_ts)$estimate
ts.plot(incendios_ts,
xlab="Periodo temporal ",
ylab="Número",
main= "Evolución del número de incendios")
En este caso, la evolución de \(T_t\) es una curva que cambia progresivamente. Como ventajas con respecto al cálculo de las tendencias realizadas con los métodos precedentes, el análisis de la tendencia evolutiva permite conocer el analizar el comportamiento pasado, detectar “fases” de crecimiento rápido o suave y desviaciones ocasionales por encima o por debajo de la tendencia, suavizando las fluctuaciones. Sin embargo, no podemos calcular valores futuros.
Antes de proceder al cálculo de las medias móviles, debe analizarse dónde se producen los puntos de cambio de esa serie temporal.
Esta prueba se suele aplicar para detectar un punto de cambio en series temporales. Verifica si se cumple H0: la variable sigue una o más distribuciones que tienen el mismo parámetro de localización (es decir, no hay cambio), frente a HA, en la que existe un punto de cambio.
pettitt.test(reyes.ts) # Puntos de cambio: cuando el valor de una serie temporal cambia bruscamente
22] reyes.ts[
pettitt.test(reyes.ts)$statistic # K máximo, valor absoluto del estadístico U
pettitt.test(reyes.ts)$estimate # Probable punto de cambio
pettitt.test(reyes.ts)$p.value # the p-value del test
Una media móvil representa el valor promedio de una variable durante un periodo de tiempo, que se calcula de manera sucesiva.
Figura 9
La forma más fácil de calcular un promedio móvil en R es usar la
función rollmean()
del paquete zoo, que
requiere requiere el parámetro k
, que es el paso o duración
del número de años sobre los que se calcula la media móvil (el
denominador de la ecuación inferior).
if (!require("zoo")) install.packages("zoo")
library(zoo)
<- rollmean(reyes.ts,
media_movil k = 13,
fill = NA)
ts.plot(reyes.ts,
xlab="Reinado",
ylab="Duración en años",
main= "Duración de los reinados de reyes ingleses")
points(reyes.ts)
lines(media_movil,
col="black",
lwd=4)
Hay diferentes tipos de filtros para suavizar una serie temporal. Un
filtro loess
es un método no paramétrico, por lo que, a
diferencia de las medias móviles, dependemos menos de la elección del
paso (nivel de suavidad). .
plot(reyes.ts) # Dibuja los datos
lines(lowess(time(reyes.ts),reyes.ts), # Suaviza la línea
col='blue')
Otro procedimiento para eliminar la tendencia es diferenciar una serie (es decir, calcular la diferencia entre una observación y su anterior).
<- log(reyes.ts)
x = diff(x)
dif.x plot(dif.x)
Desafío. A partir de la serie temporal de temperatura global:
pettitt.test(temperatura.ts) # Puntos de cambio: cuando el valor de una serie temporal cambia bruscamente
pettitt.test(temperatura.ts)$estimate, ] df.temperatura[
<- rollmean(temperatura.ts,
tem_mm_11 k = 11,
fill = NA)
ts.plot(temperatura.ts,
xlab="Reinado",
ylab="Duración en años",
main= "Duración de los reinados de reyes ingleses")
lines(tem_mm_11,
col="black",
lwd=4)
<- log(temperatura.ts)
log_tem = diff(log_tem)
dif_log_tem plot(dif_log_tem)
Además de variaciones a largo plazo del valor medio de una serie temporal, también debe analizarse si existen variaciones en las fluctuaciones de esa serie temporal, es decir, cambios en la variabilidad a largo plazo.
Volvamos al caso de los nacimientos. Para ver si la varianza se ha
modificado a lo largo del tiempo, agregaremos para cada año (al utilizar
el argumento freq = 12
R calcula cada 12 eventos) el valor
de la varianza
<- aggregate(nacimientos.ts,
varianza.nacimientos FUN = var) # Función varianza
plot(varianza.nacimientos)
Podemos realizar el mismo cálculo para el consumo de gas mensual en España entre 1966 y 1980.
<- read_excel("ejemplo.xlsx", sheet = "ejemplo3")
ejemplo3 <- ts(ejemplo3$gas,
gas.ts frequency=12,
start=c(1966,1))
<- aggregate(gas.ts,
varianza.gas FUN = var)
plot(varianza.gas)
A partir de este análisis, se comprueba que la variable gas.ts no es estacionaria, ya que, si bien presenta una tendencia aparentemente lineal, la amplitud de las fluctuaciones estacionales aumenta con el tiempo: su variabilidad no es constante. Muchos métodos de tratamiento de series temporales están diseñados para trabajar con series estacionarias (sin tendencia ni estacionalidad y con variabilidad constante). En caso contrario, se debe transformar la serie original estabilizando su varianza mediante varios procedimientos.
Uno de ellos es la transformación de los valores de la serie original en su logarítmo. Esta transformación funciona bien cuando la variabilidad es aproximadamente proporcional al nivel de la serie.
plot(log(gas.ts))
Un aspecto importante del análisis de una serie temporal es determinar si puede existir un comportamiento estacional dentro de esa serie. El comportamiento estacional consiste en cambios periódicos que se repiten con una frecuencia regular. Ejemplo de fenómenos con este tipo de comportamiento son:
La temperatura (anual)
El paro (trimestral)
La venta de entradas de cine (semanal).
Diversos contaminantes (diario).
¿Cómo podemos determinar si una serie ofrece un comportamiento estacional? A continuación se analiza el consumo de gas mensual en España desde 1966. Por ejemplo, dibujando un gráfico de caja y bigotes
boxplot(gas.ts ~ cycle(gas.ts))
Pare existir un ligero componente estacional, con máximos en verano.
Se puede avanzar en este aspecto calculando la ratio que supone cada mes
con respecto al total anual. Para ello, con la función
window()
se extraerá un subconjunto de la serie temporal;
si se acompaña del argumento freq = TRUE
se extrae un
subconjunto entre el comienzo y fin con un intervalo igual a su
frecuencia
<- window(gas.ts, start = c(1966,1), freq = TRUE)
gas.ene <- window(gas.ts, start = c(1966,2), freq = TRUE)
gas.feb <- window(gas.ts, start = c(1966,3), freq = TRUE)
gas.mar <- window(gas.ts, start = c(1966,4), freq = TRUE)
gas.abr <- window(gas.ts, start = c(1966,5), freq = TRUE)
gas.may <- window(gas.ts, start = c(1966,6), freq = TRUE)
gas.jun <- window(gas.ts, start = c(1966,7), freq = TRUE)
gas.jul <- window(gas.ts, start = c(1966,8), freq = TRUE)
gas.ago <- window(gas.ts, start = c(1966,9), freq = TRUE)
gas.sep <- window(gas.ts, start = c(1966,10), freq = TRUE)
gas.oct <- window(gas.ts, start = c(1966,11), freq = TRUE)
gas.nov <- window(gas.ts, start = c(1966,12), freq = TRUE) gas.dic
Creamos nuevos vectores calculando el ratio de cada uno de los meses con respecto al total anual
<- mean(gas.ene) / mean(gas.ts)
gas.ene.ratio <- mean(gas.feb) / mean(gas.ts)
gas.feb.ratio <- mean(gas.mar) / mean(gas.ts)
gas.mar.ratio <- mean(gas.abr) / mean(gas.ts)
gas.abr.ratio <- mean(gas.may) / mean(gas.ts)
gas.may.ratio <- mean(gas.jun) / mean(gas.ts)
gas.jun.ratio <- mean(gas.jul) / mean(gas.ts)
gas.jul.ratio <- mean(gas.ago) / mean(gas.ts)
gas.ago.ratio <- mean(gas.sep) / mean(gas.ts)
gas.sep.ratio <- mean(gas.oct) / mean(gas.ts)
gas.oct.ratio <- mean(gas.nov) / mean(gas.ts)
gas.nov.ratio <- mean(gas.dic) / mean(gas.ts) gas.dic.ratio
Finalmente, se creará una tabla con esos ratios para verificar si existe ese comportamiento estacional.
<- rbind(gas.ene.ratio,gas.feb.ratio,gas.mar.ratio,gas.abr.ratio,gas.may.ratio,gas.jun.ratio,
ratios.mensuales.gas
gas.jul.ratio,gas.ago.ratio,gas.sep.ratio,gas.oct.ratio,gas.nov.ratio,gas.dic.ratio)
ratios.mensuales.gas
rm(gas.ene,gas.feb,gas.mar,gas.abr,gas.may,gas.jun,
gas.jul,gas.ago,gas.sep,gas.oct,gas.nov,gas.dic)rm(gas.ene.ratio,gas.feb.ratio,gas.mar.ratio,gas.abr.ratio,gas.may.ratio,gas.jun.ratio,
gas.jul.ratio,gas.ago.ratio,gas.sep.ratio,gas.oct.ratio,gas.nov.ratio,gas.dic.ratio)
Podemos a su vez eliminar la estacionalidad mediante el cálculo de la serie mensual de diferencias estacionales de orden 12.
<- diff(gas.ts,
diff.gas.ts lag=12)
plot(diff.gas.ts)
Con la serie transformada podemos calcular el correlograma, una representación de las autocorrelaciones
<- diff.gas.ts
autocorrelograma acf(autocorrelograma)
acf(autocorrelograma, plot=FALSE)$acf # Valores numéricos de las correlaciones estimadas escribimos
Las líneas discontinuas representan las bandas de confianza de ??(k) de nivel 95% bajo la hipótesis de que la serie es un ruido blanco (incorrelada).
Las autocorrelaciones más significativas son
las correlaciones entre la observación de un mes y la del mes siguiente,
la observación de un mes con la del mismo mes del año siguiente.
Hay una versión de la prueba de Sen que tiene en cuenta el posible efecto de la estacionalidad.
sea.sens.slope(gas.ts) # Versíon que tiene en cuenta la estacionalidad
Hay una versión de la prueba de Sen que tiene en cuenta el posible efecto de la estacionalidad.
SeasonalMannKendall(gas.ts)
decompose()
La función R “decompose”, obtiene las componentes de tendencia, estacionalidad e irregular de una serie temporal a través de medias móviles, y además permite obtener los componentes en base a un esquema aditivo ó multiplicativo. Es una función generica de R, lo que significa que no requiere de la instalación de ninguna librería. Su uso es el siguiente:
decompose(x, type = c(“additive”, “multiplicative”), filter = NULL)
Para una correcta descomposición de una serie temporal, es importante distinguir entre modelos multiplicativos y modelos aditivos. En esencia:
MODELO ADITIVO: no varía la componente estacional, a pesar de la evolución en el tiempo
MODELO MULTIPLICATIVO: la variación estacional se incrementa con el tiempo
Como hemos visto anteriormente, se puede establecer el tipo de modelo analizando cómo ha evolucionado la varianza en el tiempo
Figura 10. Series temporales aditivas y multiplicativas
Este apartado se inicia con el análisis de los datos de nacimientos. Es una serie temporal aditiva, ya que no muestra cambios en la varianza a lo largo del tiempo. La función R “decompose” calcula de manera automática la tendencia y el componente estacional
<- decompose(nacimientos.ts, "additive")
nacimientos.descompuesta
<- ts(nacimientos.descompuesta$trend) # Tendencia
tendencia.descompuesta.nacimientos <- ts(nacimientos.descompuesta$seasonal) # Comportamiento estacional
componente.estacional.nacimientos <- ts(nacimientos.descompuesta$random) # Residuos (sin tendencia ni comportamiento estacional componente.aleatoria.nacimientos
Es posible obtener en un único panel los gráficos correspondientes a esos componentes de la serie original
plot(nacimientos.descompuesta) # Dibuja la serie estacional y los 3 componentes
También es posible dibujar cada componente de manera aislada.
plot(as.ts(nacimientos.descompuesta$trend)) # Dibuja sólo la tendencia
plot(as.ts(nacimientos.descompuesta$seasonal)) # Dibuja sólo la componente estacional
plot(as.ts(nacimientos.descompuesta$random)) # Dibuja sólo la componente aleatoria
Otra manera de calcular los valores de la componente aleatoria una vez eliminada la tendencia y la componente estacional
<- nacimientos.ts - (nacimientos.descompuesta$seasonal + nacimientos.descompuesta$trend)
nacimientos.componente.aleatoria plot(as.ts(nacimientos.componente.aleatoria))
Los datos obtenidos de la función decompose()
pueden ser
sometidos a procedimientos adicionales, como los vistos anteriormente.
Por ejemplo, podemos calcular el coeficiente de correlación de Spearman
para establecer la significación de la tendencia.
cor.test(nacimientos.descompuesta$trend,
time(nacimientos.ts),
method = "spearman")
plot(as.ts(nacimientos.descompuesta$trend))
pettitt.test(na.omit(nacimientos.descompuesta$trend))
na.omit(nacimientos.descompuesta$trend)[78]
rm(list=ls())
Desafío. - Importa el fichero series_temporales_2.xlsx,
que contiene las variables hn
(banquisa del hemisferio N) y
hs
(banquisa del hemisferio S) como series temporales (hoja
de cálculo banquisa
).
<- read_excel("TEMA_4/series_temporales_2.xlsx",
df.banquisa sheet = "Banquisa")
<- ts(df.banquisa$hn,
hn.ts frequency=12,
start=c(1978,11))
<- ts(df.banquisa$hs,
hs.ts frequency=12,
start=c(1978,11))
par(mfrow=c(1,2))
plot(hn.ts)
plot(hs.ts)
par(mfrow=c(1,1))
boxplot(hn.ts ~ cycle(hn.ts))
boxplot(hs.ts ~ cycle(hs.ts))
<- decompose(hn.ts, "additive")
hn.ts.descompuesta plot(hn.ts.descompuesta)
cor.test(hn.ts.descompuesta$trend,
time(hn.ts),
method = "spearman")
SeasonalMannKendall(hn.ts)
sea.sens.slope(hn.ts) # Versión que tiene en cuenta la estacionalidad
<- decompose(hs.ts, "additive")
hs.ts.descompuesta plot(hs.ts.descompuesta)
cor.test(hs.ts.descompuesta$trend,
time(hs.ts),
method = "spearman")
SeasonalMannKendall(hs.ts)
sea.sens.slope(hs.ts) # Versión que tiene en cuenta la estacionalidad
Un número índice se utiliza para medir los cambios en la magnitud de una variable o grupo de variables con respecto al tiempo. Permiten estudiar las variaciones en el tiempo de una o varias magnitudes de manera conjunta, independientemente de las unidades originales en las que esté medida cada magnitud.
¿Cuál es su utilidad:
Proporcionan la evolución respecto a un momento de referencia.
Son Adimensionales: permite comparar la evolución de diferentes series temporales expresadas en unidades diferentes.
Podemos clasificar todos estos índices en tres tipos:
Números índices de precios: miden cambios relativos en los precios de los productos básicos durante un período.
Números índices de cantidad: miden los cambios relativos en el volumen de una producción.
Números índices de valor: combinación de cambios en el precio y la cantidad.
Cuando usamos los números índice para comparar precios o cantidades de un solo producto, llamamos a estos números índice números índice simples. En ocasiones, puede ser necesario comparar los cambios en los precios o cantidades de muchos productos básicos, y estos precios o cantidades pueden estar en diferentes unidades. Los números índice construidos para este caso se denominan números índice agregados. Por lo tanto, tenemos dos métodos para construir números índice:
Números de índice simples
Números de índice agregados
Existen varios tipos:
Índices simples:
Índices complejos: se trabaja con más de una magnitud a la vez
Existen diferentes paquetes estadísticos para el cálculo de números índice. En este caso, se ha elegido el paquete IndexNumber, ya que contiene diferentes funciones para el cálculo de números índices.
if (!require("IndexNumber")) install.packages("IndexNumber")
library(IndexNumber)
Los números índice simples se calcula sobre los valores de una sola magnitud. Pueden distinguirse a su vez dos subtipos, en función del modO de cálculo del periodo de referencia, también conocido como periodo base (\(y_{i0}\)).
En los números índice simples este periodo de referencia es único, anque puede situarse en cualquier punto de la serie temporal (el primer valor, el último o uno intermedio). A este periodo base se le asigna el valor 100; los restantes momentos en el tiempo se calculan como porcentajes respecto al valor de referencia según la siguiente función:
Figura 11. Fórmula del cálculo del periodo base
Figura 12. Fórmula del cálculo del periodo base
<- c(70,75,77,77,85,90) v1
Cálculo de un índice simple
<- index.number.serie(v1, # Vector o dataframe del que se toman los datos.
indice_simple "v1", # Nombre de la variable a calcular
opt.plot=TRUE, # TRUE dibuja un gráfico con la evolución del índice.
opt.summary=TRUE) # TRUE proporciona un resumen estadístico de la variable
$Summary # Resumen estadístico
indice_simple$Index # Valores del índice
indice_simple
<- as.data.frame(indice_simple$Index) # Conversión en dataframe nuevo.indice.simple
La elección de este periodo base es importante, ya que su valor es anómalo tendría una repercusión negativa en los restantes valores del índice calculado. Por eso, es conveniente que sea un valor lo más “normal” posible. Una alternativa es el cálculo de los índices simples encadenados, en los que el periodo base no es único, sino que cambia con el tiempo, normalmente el intervalo temporal anterior.
Figura 13. Ejemplo de números índice encadenados
<- index.number.chain(v1, # Vector conteniendo la magnitud
indice_encadenado "v1", # Nombre de la variable estudiada
opt.plot=TRUE, # TRUE proporciona un gráfico
opt.summary=TRUE) # TRUE proporciona un resumen estadístico
<- as.data.frame(indice_encadenado$Index) nuevo.indice.encadenado
Desafío.
<- c(10,12,16,20,25,22)
v2 <- index.number.serie(v2, # Vector o dataframe del que se toman los datos.
v2_indice_simple "v2", # Nombre de la variable a calcular
opt.plot=TRUE, # TRUE dibuja un gráfico con la evolución del índice.
opt.summary=TRUE) # TRUE proporciona un resumen estadístico de la variable
<- index.number.chain(v2, # Vector conteniendo la magnitud
v2_indice_encadenado "v2", # Nombre de la variable estudiada
opt.plot=TRUE, # TRUE proporciona un gráfico
opt.summary=TRUE) # TRUE proporciona un resumen estadístico
<- cbind(v2, v2_indice_simple, v2_indice_encadenado)
df_v2
<- c(120,125,128,130,137,145)
v3 <- index.number.serie(v3, # Vector o dataframe del que se toman los datos.
v3_indice_simple "v3", # Nombre de la variable a calcular
opt.plot=TRUE, # TRUE dibuja un gráfico con la evolución del índice.
opt.summary=TRUE) # TRUE proporciona un resumen estadístico de la variable
<- index.number.chain(v3, # Vector conteniendo la magnitud
v3_indice_encadenado "v3", # Nombre de la variable estudiada
opt.plot=TRUE, # TRUE proporciona un gráfico
opt.summary=TRUE) # TRUE proporciona un resumen estadístico
<- cbind(v3, v3_indice_simple, v3_indice_encadenado) df_v3
Sirven para estudiar la evolución conjunta de diferentes variables, en los que la importancia relativa de una de ellas es superior a las restantes (Figura 14). Una posible solución, la de promediar las diferentes series de números índices no sería efectiva, ya que no reflejaría la mayor importancia relativa de esa variable
Figura 14. Ejemplo de números índice simples promediados
Para solucionar este inconveniente se recurre a ponderar, es decir, a proporcionar un peso diferente a cada índice dependiendo de su importancia, según la siguiente fórmula:
Figura 15. Fórmula ponderaciones
donde \(w_i\) es el peso o ponderación que se asigna a cada variable.
<- matrix(c(1,2,5,15,1.2,1.9,4.8,16, 1.3,1.95,5.1,15.5), ncol = 3)
precio <- matrix(c(150,430,300,250, 140, 420, 350, 220, 180, 450, 360, 280), ncol = 3) cantidad
Para elaborar este tipo de índices existen diferentes métodos; los más conocidos son el método de Laspeyres, el método de Paasche y el método de Fisher.
Este índice tiene la ventaja de requerir un menor número de variables y reflejar adecuadamente el peso de cada componente en el total. Su mayor inconveniente es que no contempla la evolución de las variables (puede que el peso de cada magnitud varíe durante el periodo de análisis).
Figura 16. Fórmula índice Laspeyres
laspeyres.index.number(precio, #
#
cantidad, "Precio", # Etiqueta de la variable
opt.plot=TRUE,
opt.summary=TRUE)
Su mayor ventaja es que refleja posibles cambios temporales en las variables, pero requiere más datos.
Figura 17. Fórmula índice Laspeyres
paasche.index.number(precio,
cantidad,"Resultado",
opt.plot=TRUE,
opt.summary=TRUE)
Desafío.
A partir de los siguientes datos: p <- c(11.31,11.22,11.64, 12.66, 13.68, 13.94, 14.79, 16.06, 8.20, 8.03, 8.03, 9.24) q <- c(1.270, 1.225,1.149,0.958, 0.068, 0.066, 0.048, 0.033, 3.829, 3.727, 3.365, 2.854)
Crea sendas matrices con 3 columnas.
Calcula el índice de Laspeyres
Calcula el índice de Paasche
ACTIVIDADES DE EVALUACIÓN CONTINUA
El fichero word 04_Actividad_evaluacion_continua_2023 contiene una serie de actividades encaminadas a poner en práctica los conocimientos adquiridos. Cada alumnos deberá elaborar un script que contenga los procedimientos necesarios para responder a las cuestiones planteadas, y enviarlo posteriormente al profesor a través de correo electrónico.