library(tibble)
library(tsibble)
library(dplyr)
library(lubridate)
library(ggplot2)
library(feasts)
library(GGally)
library(readr)
library(knitr)
library(kableExtra)
library(janitor)
El cambio climático es uno de los fenómenos más estudiados en la actualidad, y su principal evidencia es el aumento progresivo de la temperatura promedio global. Este incremento ha sido documentado tanto mediante mediciones directas como a través de diversos indicadores climáticos.
En este informe se analiza la temperatura promedio diaria registrada en diferentes ciudades del mundo, con el fin de estudiar su comportamiento en el tiempo y evaluar posibles señales asociadas al calentamiento global. El análisis se enfoca particularmente en la temperatura de Ucrania entre los años 2015 y 2020, permitiendo explorar patrones, tendencias y estacionalidad en un periodo reciente.
El dataset utilizado proviene de la University of Dayton, que recopiló información histórica de temperatura a nivel global. Este conjunto de datos es adecuado para el análisis por diversas razones:
Para este estudio se construyó una serie temporal mensual de temperatura promedio para Ucrania:
Este periodo permite observar la evolución reciente del clima en el país y facilita la aplicación de técnicas de análisis de series de tiempo como descomposición, estacionalidad, tendencia y suavizamiento.
df <- read_csv("C:/Users/USUARIO/Downloads/city_temperature.csv")
# Filtramos
df_filtrado <- df |>
filter(
Country == "Ukraine",
Year >= 2015 & Year <= 2020,
AvgTemperature != -99
)
df_filtrado
## # A tibble: 1,947 × 8
## Region Country State City Month Day Year AvgTemperature
## <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 Europe Ukraine <NA> Kiev 1 1 2015 27.9
## 2 Europe Ukraine <NA> Kiev 1 2 2015 34.3
## 3 Europe Ukraine <NA> Kiev 1 3 2015 36.6
## 4 Europe Ukraine <NA> Kiev 1 4 2015 32.9
## 5 Europe Ukraine <NA> Kiev 1 5 2015 30.3
## 6 Europe Ukraine <NA> Kiev 1 6 2015 14.5
## 7 Europe Ukraine <NA> Kiev 1 7 2015 8.2
## 8 Europe Ukraine <NA> Kiev 1 8 2015 7.7
## 9 Europe Ukraine <NA> Kiev 1 9 2015 24
## 10 Europe Ukraine <NA> Kiev 1 10 2015 34.3
## # ℹ 1,937 more rows
En este caso se filtraron los datos correspondientes a Ucrania, dado que es el país seleccionado como objeto de estudio para este análisis. Además, debido a que el dataset contiene un rango amplio de años, se decidió trabajar únicamente con el periodo 2015–2020.
Este intervalo de cinco años resulta adecuado para identificar patrones relevantes como tendencias, estacionalidad y posibles ciclos, sin perder claridad en la interpretación y manteniendo un enfoque en datos recientes.
df_ts <- df_filtrado |>
mutate(
fecha = make_date(Year, Month, Day)
) |>
as_tsibble(index = fecha)
df_ts
## # A tsibble: 1,947 x 9 [1D]
## Region Country State City Month Day Year AvgTemperature fecha
## <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <date>
## 1 Europe Ukraine <NA> Kiev 1 1 2015 27.9 2015-01-01
## 2 Europe Ukraine <NA> Kiev 1 2 2015 34.3 2015-01-02
## 3 Europe Ukraine <NA> Kiev 1 3 2015 36.6 2015-01-03
## 4 Europe Ukraine <NA> Kiev 1 4 2015 32.9 2015-01-04
## 5 Europe Ukraine <NA> Kiev 1 5 2015 30.3 2015-01-05
## 6 Europe Ukraine <NA> Kiev 1 6 2015 14.5 2015-01-06
## 7 Europe Ukraine <NA> Kiev 1 7 2015 8.2 2015-01-07
## 8 Europe Ukraine <NA> Kiev 1 8 2015 7.7 2015-01-08
## 9 Europe Ukraine <NA> Kiev 1 9 2015 24 2015-01-09
## 10 Europe Ukraine <NA> Kiev 1 10 2015 34.3 2015-01-10
## # ℹ 1,937 more rows
Como se observa, el tsibble resultante está definido con una frecuencia diaria, debido a que cada fila corresponde a un día específico entre 2015 y 2020. Aunque esta granularidad ofrece detalle, trabajar con series diarias puede dificultar la identificación visual de patrones como estacionalidad o tendencias, ya que el gráfico tiende a volverse ruidoso por la gran cantidad de observaciones.
Para facilitar el análisis y obtener una visión más clara de la evolución temporal, resulta más adecuado agregar la serie al nivel mensual. Al trabajar por meses, se reducen las fluctuaciones día a día, permitiendo identificar con mayor nitidez los patrones estacionales y las tendencias a lo largo de los años. Además, este nivel de agregación es coherente con muchos análisis climáticos y facilita la interpretación del comportamiento general de la variable.
df_mensual <- df_ts |>
mutate(fecha_mensual = yearmonth(fecha)) |>
index_by(fecha_mensual) |>
summarise(
AvgTemperature = mean(AvgTemperature, na.rm = TRUE)
)
df_mensual
## # A tsibble: 65 x 2 [1M]
## fecha_mensual AvgTemperature
## <mth> <dbl>
## 1 2015 ene. 30.6
## 2 2015 feb. 29.9
## 3 2015 mar. 40.4
## 4 2015 abr. 48.5
## 5 2015 may. 60.2
## 6 2015 jun. 67.9
## 7 2015 jul. 70.6
## 8 2015 ago. 71.2
## 9 2015 sep. 63.4
## 10 2015 oct. 43.7
## # ℹ 55 more rows
autoplot(df_mensual, AvgTemperature) +
labs(
title = "Serie Mensual de Temperatura Promedio",
x = "Fecha",
y = "Temperatura Promedio"
) +
theme_minimal()
El gráfico de la serie mensual muestra una estacionalidad marcada y consistente a lo largo de los años. Se observa que los valores de temperatura alcanzan su máximo aproximadamente en junio, mientras que los mínimos se presentan alrededor de enero. Este patrón se repite de manera regular cada año dentro del periodo analizado, lo que confirma la presencia de un comportamiento estacional fuerte, característico de ciclos climáticos anuales. La estabilidad del patrón refuerza la idea de que la temperatura promedio sigue una dinámica estacional bien definida, con veranos más cálidos e inviernos más fríos, replicándose de forma predecible en cada año.
gg_season(df_mensual, AvgTemperature) +
labs(
title = "Estacionalidad Mensual de la Temperatura",
x = "Mes",
y = "Temperatura Promedio"
) +
theme_minimal()
En términos generales, las temperaturas más bajas se presentan entre enero y febrero, mientras que a partir de marzo inicia un incremento progresivo que alcanza su máximo entre junio y julio. Posteriormente, se evidencia un descenso gradual desde agosto hasta diciembre, completando así el ciclo anual. Además, se identifica un ligero incremento en las temperaturas máximas durante los meses más cálidos (junio y julio), lo cual sugiere que el cambio climatico podria ser una causa
Aunque todas las líneas siguen una forma similar, existen pequeñas diferencias entre años —especialmente en los meses de invierno y mediados de año—, lo cual refleja variaciones naturales propias de cada período, pero sin romper el patrón estacional dominante.
df_mensual |>
ACF(AvgTemperature) |>
autoplot() +
labs(title = "ACF de la temperatura mensual",
y = "Autocorrelación",
x = "Rezago")
Autocorrelaciones altas y significativas en los primeros rezagos Los primeros rezagos muestran autocorrelaciones positivas y por encima de los límites de significancia. Esto indica que la temperatura de un mes está fuertemente relacionada con la de los meses inmediatamente anteriores, lo cual es esperado en series climáticas debido a la inercia térmica.
Oscilación entre rezagos positivos y negativos A partir del rezago 4–6 se observan autocorrelaciones negativas, seguidas nuevamente de valores positivos alrededor del rezago 11–13. Este comportamiento oscilatorio es característico de series con fuerte estacionalidad periódica, donde los valores suben y bajan siguiendo un ciclo regular.
Pico claro en el rezago 12 El rezago 12 muestra una autocorrelación claramente significativa y muy elevada. Esto confirma que la serie presenta una estacionalidad anual, coherente con una frecuencia mensual (12 meses).
df_mensual |>
PACF(AvgTemperature) |>
autoplot() +
labs(title = "PACF de la temperatura mensual",
y = "Autocorrelación parcial",
x = "Rezago")
1: Rezago 1 altamente significativo
El rezago 1 presenta un valor de autocorrelación parcial muy elevado (cercano a 0.8), lo que indica que la temperatura de un mes depende fuertemente de la del mes inmediatamente anterior, incluso después de controlar por los demás rezagos.
2: Rezagos negativos entre 3 y 6 meses
Entre los rezagos 3 y 6 se observan autocorrelaciones parciales negativas y significativas. Esto refleja que, una vez controlada la influencia de los rezagos previos, existe una relación inversa moderada entre la temperatura actual y la de 3 a 6 meses atrás. Este patrón es coherente con la transición entre estaciones opuestas (por ejemplo, verano - invierno)
La serie de temperatura mensual analizada no es estacionaria. Esto se evidencia tanto en el comportamiento del gráfico temporal como en las funciones de autocorrelación (ACF y PACF).
En primer lugar, el gráfico de la serie muestra un patrón estacional anual muy marcado y consistente, en el cual las temperaturas se repiten siguiendo el mismo ciclo cada año. La presencia de estacionalidad implica que la media de la serie cambia de manera sistemática a lo largo del año, lo cual viola uno de los supuestos fundamentales de estacionariedad: que la media debe ser constante en el tiempo.
Por otro lado, el ACF exhibe picos significativos en el rezago 12 y en múltiplos de este, lo cual confirma la existencia de un componente estacional fuerte que se repite cada año. Además, la lenta disminución de las autocorrelaciones en los primeros rezagos indica que la serie posee memoria larga, otro indicio de no estacionariedad en nivel.
Aunque la serie no muestra una tendencia marcada a largo plazo (es relativamente estable entre años), la estacionalidad regular es suficiente para clasificar la serie como no estacionaria en su forma original, ya que sus propiedades estadísticas cambian según la época del año.
En esta serie no es necesario aplicar transformaciones matemáticas, ya que la varianza se mantiene estable a lo largo del tiempo. En particular:
La diferencia entre los meses fríos y cálidos permanece prácticamente constante cada año, lo cual indica que la amplitud de la serie no cambia.
No se observa un incremento en la variabilidad durante los años más cálidos; es decir, la serie no presenta mayor dispersión conforme aumentan los valores.
La variable se mueve dentro de un rango relativamente pequeño (aproximadamente entre 12°C y 20°C), lo que reduce la necesidad de estabilizar la varianza mediante logaritmos, raíces u otras transformaciones.
Por estas razones, las transformaciones como log, Box-Cox o raíz cuadrada no aportan beneficios significativos en este caso.
dcmp <- df_mensual |>
model(
stl = STL(AvgTemperature)
)
components(dcmp) |> autoplot()
Para analizar la estructura subyacente de la serie de temperatura promedio en Ucrania, se aplicó el método STL (Seasonal and Trend decomposition using Loess), que permite descomponer la serie original en tres componentes fundamentales: tendencia, estacionalidad y residuos.
El gráfico de descomposición STL revela un patrón estacional muy pronunciado y consistente, con una amplitud aproximada de ±20°C. Este componente captura el ciclo anual característico del clima ucraniano:
Máximos en julio-agosto: Temperaturas promedio cercanas a los 65-70°F (≈18-21°C) Mínimos en enero-febrero: Temperaturas promedio alrededor de 25-30°F (≈-4 a -1°C)
El análisis del componente de tendencia muestra:
Tendencia inicial descendente (2015-2017): Disminución gradual desde aproximadamente 51°F hasta 48°F (≈10.5 a 8.9°C) Estabilización y ligero ascenso (2017-2019): La tendencia se mantiene relativamente constante alrededor de 49°F (≈9.4°C) Incremento reciente (2019-2020): Aumento notable hacia los 51°F (≈10.5°C)
Esta variación en la tendencia, aunque moderada (rango de ≈3°F), podría reflejar variabilidad climática interanual o potencialmente estar asociada a patrones de calentamiento global observados en Europa del Este durante este período.
Los residuos presentan las siguientes características:
Fluctuaciones aleatorias: Oscilan principalmente entre ±5°F, lo cual representa variabilidad de corto plazo no capturada por los componentes estacional y de tendencia Distribución aproximadamente simétrica: La mayoría de los residuos se concentran cerca de cero, indicando un buen ajuste del modelo STL Valores atípicos ocasionales: Se observan algunos picos (especialmente en 2018 y 2020) que podrían corresponder a eventos meteorológicos extremos, olas de calor o frío inusuales
La magnitud relativamente pequeña de los residuos en comparación con el componente estacional sugiere que la mayor parte de la variabilidad en la serie es explicada por el patrón estacional anual.
temp_ma12 <- df_mensual |>
mutate(`12-MA` = slider::slide_dbl(
AvgTemperature,
mean,
.before = 6,
.after = 6,
complete = TRUE
))
temp_ma12 |>
autoplot(AvgTemperature) +
geom_line(aes(y = `12-MA`), colour = "#D55E00") +
labs(
y = "Temperatura promedio",
title = "Promedio móvil de 12 periodos (12-MA)"
)
Se aplicó un promedio móvil de 12 períodos (12-MA) a la serie de temperatura mensual con el objetivo de eliminar el componente estacional y revelar de manera más clara la tendencia subyacente de largo plazo. Este método es particularmente apropiado para series con periodicidad anual (12 meses), ya que promedia un ciclo completo y neutraliza el efecto de la estacionalidad. Interpretación del gráfico En el gráfico se presentan dos series:
Serie original (línea negra): Muestra las fluctuaciones mensuales con la pronunciada variabilidad estacional característica Promedio móvil 12-MA (línea naranja): Representa la tendencia suavizada, libre del efecto estacional
Hallazgos principales 1. Eliminación efectiva de la estacionalidad El promedio móvil de 12 períodos cumple exitosamente su función al suavizar completamente las oscilaciones estacionales, produciendo una curva continua que oscila suavemente alrededor de los 48-52°F (≈9-11°C). Esto permite observar con claridad los cambios en la temperatura promedio anual sin la interferencia del ciclo verano-invierno. 2. Comportamiento de la tendencia de largo plazo El análisis de la línea naranja revela un patrón de tendencia con las siguientes fases: Período 2015-2016 (Fase inicial descendente)
La tendencia inicia alrededor de 50-51°F (≈10-10.5°C) Presenta un descenso gradual hacia finales de 2016
Período 2016-2019 (Fase de estabilización)
La tendencia se estabiliza en un rango relativamente estrecho entre 48-50°F (≈9-10°C) Se observan fluctuaciones mínimas, lo que sugiere temperaturas promedio anuales consistentes durante este período Esta estabilidad podría reflejar condiciones climáticas relativamente homogéneas año tras año
Período 2019-2020 (Descenso pronunciado)
A partir de mediados de 2019, la tendencia muestra un descenso notable que se acentúa dramáticamente hacia finales de 2020 La tendencia alcanza su nivel más bajo de todo el período analizado, cayendo por debajo de 42°F (≈5.5°C) Este descenso es el cambio más significativo observado en toda la serie suavizada —
La tendencia muestra un comportamiento no lineal y varía a lo largo del período:
Este comportamiento sugiere que factores climáticos regionales (oscilaciones atmosféricas, circulación, variabilidad natural) influyeron más que la tendencia climática global durante este intervalo específico.
La serie presenta una estacionalidad marcada y extremadamente consistente, siendo el componente dominante:
Este patrón coincide con el clima continental templado de Ucrania, mostrando veranos cálidos e inviernos fríos bien diferenciados.
Los residuos reflejan variabilidad de corto plazo no explicada por tendencia ni estacionalidad:
Los resultados indican que la descomposición captura adecuadamente la estructura principal de la serie.
El análisis de autocorrelación muestra:
La estacionalidad explica la mayoría de la variación de la serie (±20°F), mientras que los cambios de tendencia son pequeños (≈3°F entre 2015–2019).
El análisis revela que la estacionalidad anual es el componente dominante en la temperatura mensual de Ucrania, mostrando un patrón estable y predecible. Aunque existe una tendencia variable, el comportamiento a largo plazo es incierto debido al corto período analizado.
La predictibilidad de corto plazo es alta gracias al ciclo estacional, mientras que las proyecciones de mediano y largo plazo requieren más información y modelos más complejos.
Rajkumar, S. (2020). Daily Temperature of Major Cities.
Kaggle.
Disponible en: https://www.kaggle.com/datasets/sudalairajkumar/daily-temperature-of-major-cities
Castellón, N. (2024, mayo 15). Autocorrelación simple (ACF) vs
autocorrelación parcial (PACF) [Publicación de LinkedIn].
LinkedIn.
Disponible en: https://www.linkedin.com/posts/naren-castellon-1541b8101_autocorrelación-simple-acf-vs-autocorrelación-activity-7141139527137427457-eBGy/
DataCamp. (s.f.). Time series decomposition tutorial.
DataCamp.
Disponible en: https://www.datacamp.com/es/tutorial/time-series-decomposition
Club de Capitales. (s.f.). Promedio móvil o media móvil.
Club de Capitales.
Disponible en: https://clubdecapitales.com/educacion/promedio-movil-o-media-movil/