En esta práctica aprenderemos a descargar, limpiar y visualizar datos climáticos históricos utilizando el conjunto de datos CRU TS 4.09 (Climatic Research Unit gridded Time Series), que cubre el período 1901–2024 con resolución mensual para más de 190 países.
Trabajaremos con cuatro variables principales:
| Código | Variable | Unidad |
|---|---|---|
pre |
Precipitación | mm |
tmp |
Temperatura media | °C |
tmn |
Temperatura mínima | °C |
tmx |
Temperatura máxima | °C |
Fuente de los datos: University of East Anglia, Climatic Research Unit.
URL base:https://crudata.uea.ac.uk/cru/data/hrg/cru_ts_4.09/
Seleccionamos las cuatro variables climáticas y un conjunto amplio de países del G20 más la Unión Europea.
variables <- c("pre", "tmn", "tmp", "tmx")
g20_countries <- unique(c(
"Argentina", "Australia", "Brazil", "Canada", "China",
"France", "Germany", "India", "Indonesia", "Italy",
"Japan", "Mexico", "Russia", "Saudi_Arabia", "South_Africa",
"South_Korea", "Turkey", "United_Kingdom", "USA",
"Austria", "Belgium", "Bulgaria", "Croatia", "Cyprus",
"Czech_Republic", "Denmark", "Estonia", "Finland", "Greece",
"Hungary", "Ireland", "Latvia", "Lithuania", "Luxembourg",
"Malta", "Netherlands", "Poland", "Portugal", "Romania",
"Slovakia", "Slovenia", "Spain", "Sweden"
))
cat("Total de países:", length(g20_countries), "\n")## Total de países: 43
## Variables: pre, tmn, tmp, tmx
.perEl loop descarga cada archivo solo si no existe ya en el directorio de trabajo, por lo que es seguro volver a correr el bloque sin re-descargar todo. Los errores 404 se capturan e imprimen sin detener la ejecución.
⚠️ Antes de hacer Knit: asegúrate de que tu directorio de trabajo es correcto (
setwd) y que tienes conexión a internet. La descarga completa puede tardar varios minutos.
base_url <- "https://crudata.uea.ac.uk/cru/data/hrg/cru_ts_4.09/crucy.2503061057.v4.09/countries"
total <- length(g20_countries) * length(variables)
contador <- 0
for (country in g20_countries) {
for (var in variables) {
contador <- contador + 1
file <- paste0("crucy.v4.09.1901.2024.", country, ".", var, ".per")
if (!file.exists(file)) {
tryCatch(
{
download.file(
url = paste0(base_url, "/", var, "/", file),
destfile = file,
mode = "wb",
quiet = TRUE
)
message(sprintf("[%d/%d] Descargado: %s", contador, total, file))
},
error = function(e) message(sprintf("[%d/%d] 404 – no encontrado: %s", contador, total, file))
)
} else {
message(sprintf("[%d/%d] Ya existe, omitido: %s", contador, total, file))
}
}
}
message("✔ Descarga completada.").perCada archivo .per tiene 18 columnas: año, doce meses,
cuatro estaciones (MAM, JJA, SON, DJF) y el valor anual (ANN). Las
primeras 4 líneas son encabezado y se omiten con
skip = 4.
col_names <- c("Year", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
"MAM", "JJA", "SON", "DJF", "ANN")Nota sobre estaciones: - DJF (Dec–Feb): Invierno
- MAM (Mar–May): Primavera
- JJA (Jun–Ago): Verano
- SON (Sep–Nov): Otoño
Cada archivo .per se lee con read_table(),
saltando las 4 primeras líneas de encabezado. El valor
-999.0 indica dato faltante y se convierte automáticamente
a NA. El resultado es una lista nombrada con la clave
"Pais_variable" (ej. "Mexico_tmp").
climate_data <- list()
no_encontrados <- c()
for (country in g20_countries) {
for (var in variables) {
file <- paste0("crucy.v4.09.1901.2024.", country, ".", var, ".per")
if (file.exists(file)) {
df <- read_table(file, skip = 4, col_names = col_names,
na = "-999.0", show_col_types = FALSE)
df$Country <- country
df$Variable <- var
climate_data[[paste0(country, "_", var)]] <- df
} else {
no_encontrados <- c(no_encontrados, file)
}
}
}
cat(sprintf("Entradas cargadas en climate_data: %d de %d esperadas\n",
length(climate_data),
length(g20_countries) * length(variables)))## Entradas cargadas en climate_data: 172 de 172 esperadas
if (length(no_encontrados) > 0) {
cat(sprintf("Archivos no encontrados (%d):\n", length(no_encontrados)))
cat(paste(" -", no_encontrados, collapse = "\n"), "\n")
}
# Vista rapida de la estructura de un dataframe de ejemplo
cat("\nEstructura de Mexico_tmp:\n")##
## Estructura de Mexico_tmp:
## spc_tbl_ [124 × 20] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ Year : num [1:124] 1901 1902 1903 1904 1905 ...
## $ Jan : num [1:124] 16.1 15.3 15.5 14.6 15.4 15.1 17.1 16.1 16.9 15.5 ...
## $ Feb : num [1:124] 16.3 16.1 15.3 17.5 14.7 16.3 17.7 16.4 16.7 15.4 ...
## $ Mar : num [1:124] 18.6 18.4 18.1 20.1 19 18 20.2 20 18.9 19.5 ...
## $ Apr : num [1:124] 20.5 22.1 21 21.6 20.8 21.1 21.2 21.8 21.1 21.1 ...
## $ May : num [1:124] 23.2 24.1 22.7 23.1 23.6 23.3 22.3 23.3 23.2 23.5 ...
## $ Jun : num [1:124] 24.7 25.6 24 24.6 24.9 25.4 24.5 25.1 25.1 24.8 ...
## $ Jul : num [1:124] 25.2 24.8 24.8 24.5 24.6 24.8 24.8 24.7 25.1 25 ...
## $ Aug : num [1:124] 25.2 25 24.6 24.5 25.4 24.2 24.8 24.7 24.6 25.1 ...
## $ Sep : num [1:124] 23.9 24 23.4 23.8 24.3 24 24.2 23.5 23.3 24.2 ...
## $ Oct : num [1:124] 21.9 21.7 20.8 21.2 21.4 20.7 21.7 20.4 21.2 21 ...
## $ Nov : num [1:124] 18.9 18.9 18.2 17.9 18.6 17.8 17.2 17.9 19.2 18.4 ...
## $ Dec : num [1:124] 15.7 16 15.5 15.9 14.2 16.8 16.4 16.1 14 16.1 ...
## $ MAM : num [1:124] 20.8 21.6 20.6 21.6 21.1 20.8 21.3 21.7 21.1 21.4 ...
## $ JJA : num [1:124] 25 25.1 24.5 24.5 25 24.8 24.7 24.8 24.9 25 ...
## $ SON : num [1:124] 21.6 21.5 20.8 21 21.4 20.8 21 20.6 21.3 21.2 ...
## $ DJF : num [1:124] 15.7 15.6 15.9 15.3 15.2 17.2 16.3 16.6 14.9 16.8 ...
## $ ANN : num [1:124] 20.9 21 20.3 20.8 20.6 20.6 21 20.8 20.8 20.8 ...
## $ Country : chr [1:124] "Mexico" "Mexico" "Mexico" "Mexico" ...
## $ Variable: chr [1:124] "tmp" "tmp" "tmp" "tmp" ...
## - attr(*, "spec")=
## .. cols(
## .. Year = col_double(),
## .. Jan = col_double(),
## .. Feb = col_double(),
## .. Mar = col_double(),
## .. Apr = col_double(),
## .. May = col_double(),
## .. Jun = col_double(),
## .. Jul = col_double(),
## .. Aug = col_double(),
## .. Sep = col_double(),
## .. Oct = col_double(),
## .. Nov = col_double(),
## .. Dec = col_double(),
## .. MAM = col_double(),
## .. JJA = col_double(),
## .. SON = col_double(),
## .. DJF = col_double(),
## .. ANN = col_double()
## .. )
mexico_pre <- climate_data[["Mexico_pre"]]
months <- c("Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec")
mean_monthly <- as.integer(round(sapply(months, function(m) mean(mexico_pre[[m]], na.rm = TRUE))))
sd_monthly <- as.integer(round(sapply(months, function(m) sd(mexico_pre[[m]], na.rm = TRUE))))
min_monthly <- as.integer(round(sapply(months, function(m) min(mexico_pre[[m]], na.rm = TRUE))))
max_monthly <- as.integer(round(sapply(months, function(m) max(mexico_pre[[m]], na.rm = TRUE))))
stats_mexico <- data.frame(
Mes = months,
Media = mean_monthly,
DE = sd_monthly,
Mínimo = min_monthly,
Máximo = max_monthly
)
knitr::kable(stats_mexico,
caption = "Estadísticas de precipitación mensual para México (1901–2024)",
align = "lrrrr")| Mes | Media | DE | Mínimo | Máximo |
|---|---|---|---|---|
| Jan | 22 | 9 | 3 | 52 |
| Feb | 16 | 7 | 5 | 40 |
| Mar | 14 | 6 | 4 | 42 |
| Apr | 17 | 7 | 5 | 40 |
| May | 41 | 13 | 15 | 80 |
| Jun | 100 | 21 | 57 | 149 |
| Jul | 124 | 24 | 70 | 217 |
| Aug | 125 | 24 | 79 | 192 |
| Sep | 139 | 27 | 76 | 218 |
| Oct | 79 | 24 | 18 | 135 |
| Nov | 30 | 13 | 7 | 66 |
| Dec | 26 | 12 | 5 | 66 |
bp_mexico <- barplot(
mean_monthly,
names.arg = months,
col = "deepskyblue4",
main = "Precipitación Mensual Promedio en México (1901–2024)",
ylab = "Precipitación (mm)",
xlab = "Mes",
ylim = c(0, max(mean_monthly) * 1.15),
cex.names = 0.9,
cex.axis = 0.9,
las = 1,
font.lab = 2
)
text(x = bp_mexico[, 1],
y = mean_monthly + 2,
labels = mean_monthly,
cex = 0.8,
col = "black",
adj = c(0.5, 0))
abline(h = mean(mean_monthly),
col = "red", lwd = 2, lty = 2)
legend("topleft",
legend = paste("Media anual:", round(mean(mean_monthly)), "mm"),
col = "red", lty = 2, lwd = 2, bty = "n")Precipitación mensual promedio en México (1901–2024)
Interpretación: La precipitación en México es claramente estacional, con un pico marcado en los meses de verano (junio–septiembre) asociado a la temporada de lluvias. Los meses de invierno presentan valores muy bajos.
annual_pre <- data.frame(Country = character(), Mean_ANN = numeric())
for (country in g20_countries) {
key <- paste0(country, "_pre")
if (key %in% names(climate_data)) {
mean_ann <- mean(climate_data[[key]]$ANN, na.rm = TRUE)
annual_pre <- rbind(annual_pre,
data.frame(Country = country, Mean_ANN = mean_ann))
}
}
# Ordenar de mayor a menor
annual_pre <- annual_pre[order(annual_pre$Mean_ANN, decreasing = TRUE), ]
knitr::kable(head(annual_pre, 10),
caption = "Top 10 países con mayor precipitación anual promedio",
digits = 1,
col.names = c("País", "Precipitación media anual (mm)"))| País | Precipitación media anual (mm) | |
|---|---|---|
| 9 | Indonesia | 2644.7 |
| 3 | Brazil | 1774.1 |
| 11 | Japan | 1698.8 |
| 16 | South_Korea | 1338.2 |
| 41 | Slovenia | 1236.2 |
| 18 | United_Kingdom | 1176.9 |
| 31 | Ireland | 1163.2 |
| 23 | Croatia | 1149.2 |
| 8 | India | 1129.0 |
| 20 | Austria | 1086.9 |
blues_palette <- colorRampPalette(c("#97FFFF", "#8DEEEE", "#79CDCD", "#528B8B", "#2F4F4F"))
colors <- blues_palette(nrow(annual_pre))[rank(annual_pre$Mean_ANN)]
bp_g20 <- barplot(
annual_pre$Mean_ANN,
names.arg = annual_pre$Country,
las = 2,
col = colors,
main = "Precipitación anual promedio por país",
ylab = "Precipitación (mm)",
ylim = c(0, max(annual_pre$Mean_ANN) * 1.15),
cex.names = 0.6,
cex.axis = 0.9,
font.lab = 2
)
text(x = bp_g20[, 1],
y = annual_pre$Mean_ANN + 5,
labels = round(annual_pre$Mean_ANN),
cex = 0.55,
col = "black",
adj = c(0.5, 0))
abline(h = mean(annual_pre$Mean_ANN),
col = "red", lwd = 2, lty = 2)
legend("topright",
legend = paste("Media G20:", round(mean(annual_pre$Mean_ANN)), "mm"),
col = "red", lty = 2, lwd = 2, bty = "n")Precipitación anual promedio — países G20 y UE
annual_tmp <- data.frame(Country = character(), Mean_ANN = numeric())
for (country in g20_countries) {
key <- paste0(country, "_tmp")
if (key %in% names(climate_data)) {
mean_ann <- mean(climate_data[[key]]$ANN, na.rm = TRUE)
annual_tmp <- rbind(annual_tmp,
data.frame(Country = country, Mean_ANN = mean_ann))
}
}
annual_tmp <- annual_tmp[order(annual_tmp$Mean_ANN, decreasing = TRUE), ]
knitr::kable(head(annual_tmp, 10),
caption = "Top 10 países más cálidos (temperatura anual promedio)",
digits = 1,
col.names = c("País", "Temperatura media anual (°C)"))| País | Temperatura media anual (°C) | |
|---|---|---|
| 9 | Indonesia | 25.9 |
| 14 | Saudi_Arabia | 25.2 |
| 3 | Brazil | 24.9 |
| 8 | India | 23.7 |
| 2 | Australia | 21.6 |
| 12 | Mexico | 21.2 |
| 35 | Malta | 19.5 |
| 24 | Cyprus | 18.2 |
| 15 | South_Africa | 17.8 |
| 38 | Portugal | 15.4 |
dark_palette <- colorRampPalette(c("brown4", "brown", "brown3", "brown2", "brown1"))
colors <- dark_palette(nrow(annual_tmp))[rank(annual_tmp$Mean_ANN)]
bp_tmp_g20 <- barplot(
annual_tmp$Mean_ANN,
names.arg = annual_tmp$Country,
las = 2,
col = colors,
main = "Temperatura anual promedio por país",
ylab = "Temperatura (°C)",
ylim = c(0, max(annual_tmp$Mean_ANN) * 1.15),
cex.names = 0.6,
cex.axis = 0.9,
font.lab = 2
)
text(x = bp_tmp_g20[, 1],
y = annual_tmp$Mean_ANN + 0.3,
labels = round(annual_tmp$Mean_ANN, 1),
cex = 0.55,
col = "black",
adj = c(0.5, 0))
abline(h = mean(annual_tmp$Mean_ANN),
col = "red", lwd = 2, lty = 2)
legend("topright",
legend = paste("Media G20:", round(mean(annual_tmp$Mean_ANN), 1), "°C"),
col = "red", lty = 2, lwd = 2, bty = "n")Temperatura anual promedio — países G20 y UE
La temperatura promedio anual de un país puede analizarse como una
serie de tiempo. Ajustar una regresión lineal
(lm) nos permite visualizar la tendencia a largo plazo.
country_ts <- climate_data[["Mexico_tmp"]]
trend <- lm(ANN ~ Year, data = country_ts)
plot(country_ts$Year, country_ts$ANN,
type = "l", col = "tomato", lwd = 2,
main = "Temperatura Promedio Anual de México (1901–2024)",
xlab = "Año", ylab = "Temperatura (°C)")
abline(trend, col = "black", lwd = 2, lty = 2)
legend("topleft",
legend = c("Temperatura anual", "Tendencia lineal"),
col = c("tomato", "black"),
lty = c(1, 2), lwd = 2, bty = "n")Serie de tiempo de temperatura anual en México con tendencia lineal
## Pendiente estimada: 0.0119 °C/año
cat(sprintf("Calentamiento total estimado (1901-2024): %.2f °C\n",
coef(trend)["Year"] * (2024 - 1901)))## Calentamiento total estimado (1901-2024): 1.47 °C
Interpretación económica: El calentamiento observado tiene implicaciones para la productividad agrícola, el consumo energético y los patrones de migración, temas centrales en la economía del desarrollo y la economía ambiental.
country_ts <- climate_data[["Mexico_pre"]]
trend <- lm(ANN ~ Year, data = country_ts)
plot(country_ts$Year, country_ts$ANN,
type = "l", col = "slateblue1", lwd = 2,
main = "Precipitación Promedio Anual de México (1901–2024)",
xlab = "Año", ylab = "Precipitación (mm)")
abline(trend, col = "black", lwd = 2, lty = 2)
legend("topleft",
legend = c("Precipitación anual", "Tendencia lineal"),
col = c("slateblue1", "black"),
lty = c(1, 2), lwd = 2, bty = "n")Serie de tiempo de precipitación anual en México con tendencia lineal
La tasa de crecimiento año a año (Year-over-Year, YoY) mide el cambio porcentual entre años consecutivos:
\[\text{YoY}_t = \frac{X_t - X_{t-1}}{X_{t-1}} \times 100\]
country_ts <- climate_data[["Mexico_tmp"]]
country_ts$YoY_growth <- c(NA, diff(country_ts$ANN) / head(country_ts$ANN, -1) * 100)
plot(country_ts$Year[-1], country_ts$YoY_growth[-1],
type = "l", col = "tomato", lwd = 2,
main = "Tasa de Crecimiento YoY de Temperatura en México (1901–2024)",
xlab = "Año", ylab = "(%)")
abline(h = 0, col = "black", lty = 2)Tasa de crecimiento YoY de la temperatura anual en México
country_ts <- climate_data[["Mexico_pre"]]
country_ts$YoY_growth <- c(NA, diff(country_ts$ANN) / head(country_ts$ANN, -1) * 100)
plot(country_ts$Year[-1], country_ts$YoY_growth[-1],
type = "l", col = "slateblue", lwd = 2,
main = "Tasa de Crecimiento YoY de Precipitación en México (1901–2024)",
xlab = "Año", ylab = "(%)")
abline(h = 0, col = "black", lty = 2)Tasa de crecimiento YoY de la precipitación anual en México
extreme_years <- data.frame(
Country = character(),
Hottest = numeric(),
Coldest = numeric(),
Year_Hot = numeric(),
Year_Cold = numeric()
)
for (country in g20_countries) {
key <- paste0(country, "_tmp")
if (key %in% names(climate_data)) {
df <- climate_data[[key]]
extreme_years <- rbind(extreme_years, data.frame(
Country = country,
Hottest = round(max(df$ANN, na.rm = TRUE), 2),
Coldest = round(min(df$ANN, na.rm = TRUE), 2),
Year_Hot = df$Year[which.max(df$ANN)],
Year_Cold = df$Year[which.min(df$ANN)]
))
}
}
knitr::kable(extreme_years,
caption = "Anos extremos de temperatura por pais",
digits = 2,
col.names = c("Pais", "Temp. maxima (C)", "Temp. minima (C)",
"Ano mas calido", "Ano mas frio"))| Pais | Temp. maxima (C) | Temp. minima (C) | Ano mas calido | Ano mas frio |
|---|---|---|---|---|
| Argentina | 16.2 | 14.2 | 2023 | 1956 |
| Australia | 22.8 | 20.7 | 2019 | 1917 |
| Brazil | 26.0 | 24.3 | 2015 | 1917 |
| Canada | -3.0 | -7.2 | 2010 | 1972 |
| China | 8.8 | 6.5 | 2024 | 1956 |
| France | 13.2 | 9.5 | 2022 | 1963 |
| Germany | 11.2 | 6.8 | 2024 | 1940 |
| India | 24.8 | 22.8 | 2009 | 1917 |
| Indonesia | 26.5 | 25.5 | 2024 | 1956 |
| Italy | 16.0 | 12.5 | 2024 | 1940 |
| Japan | 13.6 | 10.0 | 2024 | 1913 |
| Mexico | 23.1 | 20.3 | 2024 | 1903 |
| Russia | -1.7 | -6.6 | 2020 | 1969 |
| Saudi_Arabia | 26.9 | 24.2 | 2010 | 1911 |
| South_Africa | 19.4 | 16.7 | 2019 | 1907 |
| South_Korea | 14.3 | 10.5 | 2024 | 1917 |
| Turkey | 13.3 | 9.8 | 2024 | 1911 |
| United_Kingdom | 10.1 | 7.7 | 2022 | 1919 |
| USA | 10.5 | 7.4 | 2016 | 1917 |
| Austria | 9.4 | 4.6 | 2024 | 1940 |
| Belgium | 12.0 | 8.1 | 2022 | 1963 |
| Bulgaria | 13.4 | 9.2 | 2024 | 1933 |
| Croatia | 14.2 | 9.3 | 2024 | 1940 |
| Cyprus | 20.2 | 16.7 | 2024 | 1903 |
| Czech_Republic | 10.6 | 5.4 | 2024 | 1940 |
| Denmark | 10.0 | 5.9 | 2020 | 1942 |
| Estonia | 8.2 | 2.8 | 2020 | 1941 |
| Finland | 4.4 | -0.9 | 2020 | 1902 |
| Greece | 17.6 | 14.1 | 2024 | 1933 |
| Hungary | 13.3 | 8.2 | 2024 | 1940 |
| Ireland | 10.8 | 8.5 | 2023 | 1963 |
| Latvia | 8.6 | 3.4 | 2020 | 1941 |
| Lithuania | 9.1 | 3.9 | 2024 | 1941 |
| Luxembourg | 11.0 | 7.0 | 2022 | 1963 |
| Malta | 21.3 | 18.4 | 2024 | 1906 |
| Netherlands | 11.7 | 7.8 | 2024 | 1963 |
| Poland | 10.9 | 5.7 | 2024 | 1940 |
| Portugal | 17.3 | 14.1 | 2022 | 1917 |
| Romania | 12.2 | 7.3 | 2024 | 1940 |
| Slovakia | 10.5 | 5.2 | 2024 | 1940 |
| Slovenia | 11.7 | 6.7 | 2024 | 1940 |
| Spain | 15.3 | 12.1 | 2022 | 1917 |
| Sweden | 4.8 | 0.4 | 2020 | 1902 |
plot_bubble_panelLa función dibuja un panel por cada año extremo. Cuando se llama
desde un chunk de RMarkdown sin
png()/dev.off(), el gráfico se renderiza
directamente en el HTML.
plot_bubble_panel <- function(data, temp_col, year_col, title, ramp, unit) {
years <- sort(unique(data[[year_col]]))
chunks <- split(years, ceiling(seq_along(years) / 6))
global_min <- min(data[[temp_col]])
global_max <- max(data[[temp_col]])
for (i in seq_along(chunks)) {
chunk_years <- chunks[[i]]
n_panels <- length(chunk_years)
n_cols <- 3
n_rows <- ceiling(n_panels / n_cols)
par(mfrow = c(n_rows, n_cols),
mar = c(5.5, 4.5, 3.5, 1.5),
oma = c(2, 2.5, 4, 1),
bg = "white")
for (yr in chunk_years) {
sub <- data[data[[year_col]] == yr, ]
sub <- sub[order(sub[[temp_col]]), ]
n <- nrow(sub)
x <- seq_len(n)
cex_vals <- 1.2 + (sub[[temp_col]] - global_min) / (global_max - global_min) * 4.5
pal <- colorRampPalette(ramp)(100)
idx <- round((sub[[temp_col]] - global_min) / (global_max - global_min) * 99) + 1
col_vals <- pal[pmax(1, pmin(100, idx))]
local_min <- min(sub[[temp_col]])
local_max <- max(sub[[temp_col]])
y_pad <- max((local_max - local_min) * 0.45, abs(local_min) * 0.20)
ylim <- c(local_min - y_pad, local_max + y_pad)
plot(x, sub[[temp_col]],
type = "n", xlim = c(0.5, n + 0.5), ylim = ylim,
xaxt = "n", yaxt = "n", xlab = "", ylab = "",
main = yr, font.main = 2, cex.main = 1.1)
abline(h = pretty(ylim, n = 4), col = "grey88", lty = 1, lwd = 0.6)
abline(h = 0, col = "grey60", lty = 2, lwd = 0.8)
points(x, sub[[temp_col]],
pch = 21, bg = col_vals,
col = "white", cex = cex_vals, lwd = 0.6)
text(x, sub[[temp_col]] + (local_max - local_min + y_pad) * 0.14,
labels = paste0(round(sub[[temp_col]]), unit),
cex = 0.65, col = "grey20", font = 2)
axis(1, at = x, labels = sub$Country, las = 2,
cex.axis = 0.65, tick = FALSE, line = 0)
axis(2, at = pretty(ylim, n = 4),
labels = paste0(pretty(ylim, n = 4), unit),
las = 1, cex.axis = 0.65, col.axis = "grey40",
tick = TRUE, col = "grey80")
box(col = "grey80")
}
if (n_panels %% n_cols != 0) {
for (k in seq_len(n_cols - n_panels %% n_cols)) plot.new()
}
mtext(paste0(title, " [", min(chunk_years), "-", max(chunk_years), "]"),
outer = TRUE, side = 3, line = 2.2, font = 2, cex = 0.85)
mtext(paste0("Part ", i, " of ", length(chunks)),
outer = TRUE, side = 3, line = 0.8, font = 3, cex = 0.7, col = "grey50")
mtext(paste0("Annual temperature (", unit, ")"),
outer = TRUE, side = 2, line = 0.8, cex = 0.75, col = "grey30")
}
}Comparamos la temperatura media por estación para países de diferentes zonas climáticas.
selected <- c("Germany", "Mexico", "Brazil", "India",
"China", "Indonesia", "South_Africa")
seasons <- c("DJF", "MAM", "JJA", "SON")
season_labels <- c("DJF (Invierno)", "MAM (Primavera)",
"JJA (Verano)", "SON (Otoño)")
country_colors <- c("#B0E0E6", "#FFF68F", "#9ACD32", "#191970",
"#C71585", "#48D1CC", "#F4A460")
par(mfrow = c(2, 2), mar = c(6, 4, 3, 1))
for (i in seq_along(seasons)) {
s <- seasons[i]
seasonal_means <- sapply(selected, function(country) {
key <- paste0(country, "_tmp")
if (key %in% names(climate_data)) {
mean(climate_data[[key]][[s]], na.rm = TRUE)
} else NA
})
barplot(seasonal_means,
names.arg = selected,
col = country_colors,
main = season_labels[i],
ylab = "Temperatura (°C)",
ylim = c(-10, 35),
las = 2,
cex.names = 0.75,
font.lab = 2)
abline(h = 0, col = "gray50", lty = 2)
}Temperatura media estacional para 7 países de distintas zonas climáticas
Nota: La estacionalidad de DJF e JJA está invertida entre hemisferios: cuando es invierno en Alemania (DJF), es verano en Brasil y Sudáfrica.
Exploramos la relación entre temperatura y precipitación para México a lo largo del tiempo.
par(mar = c(5, 4.5, 4, 4.5))
pre_mx <- climate_data[["Mexico_pre"]][, c("Year", "ANN")]
tmp_mx <- climate_data[["Mexico_tmp"]][, c("Year", "ANN")]
colnames(pre_mx) <- c("Year", "Precipitation")
colnames(tmp_mx) <- c("Year", "Temperature")
merged_mx <- merge(pre_mx, tmp_mx, by = "Year")
cor_val <- cor(merged_mx$Temperature, merged_mx$Precipitation,
use = "complete.obs")
# ── Eje izquierdo: Precipitación ──────────────────────────────────────────────
plot(merged_mx$Year, merged_mx$Precipitation,
type = "l",
col = "steelblue",
lwd = 2,
main = "Precipitación y Temperatura Anual — México (1901–2024)",
xlab = "Año",
ylab = "Precipitación (mm)",
ylim = c(min(merged_mx$Precipitation, na.rm = TRUE) * 0.9,
max(merged_mx$Precipitation, na.rm = TRUE) * 1.1),
las = 1)
# ── Eje derecho: Temperatura ──────────────────────────────────────────────────
par(new = TRUE)
plot(merged_mx$Year, merged_mx$Temperature,
type = "l",
col = "tomato",
lwd = 2,
axes = FALSE,
xlab = "",
ylab = "",
ylim = c(min(merged_mx$Temperature, na.rm = TRUE) * 0.97,
max(merged_mx$Temperature, na.rm = TRUE) * 1.03))
axis(side = 4, las = 1, col.axis = "tomato", col = "tomato")
mtext("Temperatura (°C)", side = 4, line = 3.5, col = "tomato", font = 2)
# ── Leyenda ───────────────────────────────────────────────────────────────────
legend("topleft",
legend = c("Precipitación (mm)", "Temperatura (°C)",
paste0("r = ", round(cor_val, 3))),
col = c("steelblue", "tomato", NA),
lty = c(1, 1, NA),
lwd = c(2, 2, NA),
bty = "n",
cex = 0.85)Temperatura y precipitación anual en México (1901–2024) — doble eje
En esta práctica aprendimos a:
.per en
una lista de data frames con claves "Pais_variable".## R version 4.3.3 (2024-02-29)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Linux Mint 22.3
##
## Matrix products: default
## BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.12.0
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.12.0
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
## [5] LC_MONETARY=es_MX.UTF-8 LC_MESSAGES=en_US.UTF-8
## [7] LC_PAPER=es_MX.UTF-8 LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C
## [11] LC_MEASUREMENT=es_MX.UTF-8 LC_IDENTIFICATION=C
##
## time zone: America/Mexico_City
## tzcode source: system (glibc)
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] readr_2.2.0
##
## loaded via a namespace (and not attached):
## [1] digest_0.6.39 R6_2.6.1 fastmap_1.2.0 xfun_0.55
## [5] tzdb_0.5.0 magrittr_2.0.4 glue_1.8.0 cachem_1.1.0
## [9] tibble_3.3.1 knitr_1.51 pkgconfig_2.0.3 htmltools_0.5.9
## [13] rmarkdown_2.30 lifecycle_1.0.5 cli_3.6.5 vctrs_0.7.1
## [17] sass_0.4.10 jquerylib_0.1.4 compiler_4.3.3 rstudioapi_0.17.1
## [21] tools_4.3.3 hms_1.1.4 pillar_1.11.1 evaluate_1.0.5
## [25] bslib_0.9.0 yaml_2.3.12 crayon_1.5.3 rlang_1.1.7
## [29] jsonlite_2.0.0