::: {.alert .alert-success}

💡 OBJETIVOS DE LA ACTIVIDAD:

➤ Determinar en qué medida una localidad está afectada por la proximidad o lejanía del océano, comparando su régimen térmico con otras zonas.

➤ Calcular la diferencia entre las temperaturas medias del mes más cálido y del mes más frío, identificando cómo esta amplitud refleja el grado de continentalidad o marítimidad.

➤ Aplicar y comparar distintos índices climáticos (ara evaluar la continentalidad y comparar los resultados entre varias localidades.

➤ Interpretar la relación entre losfactores geográficos (latitud, altitud, proximidad al mar, corrientes oceánicas o relieve) y la temperatura a partir de los valores de los índices.

➤ Desarrollar habilidades de análisis climático y cartográfico.

INTRODUCCIÓN: ÍNDICES DE CONTINENTALIDAD

Los índices de continentalidad valoran el grado de influencia del continente, el mar o el océano en un territorio. Para ello tienen en cuenta la oscilación térmica anual, si ésta es amplia suele corresponder a espacios continentales, mientras que si el valor es bajo suele representar áreas con influencia oceánica, puesto que los mares, lagos y océanos tienden a amortiguar el contraste de las temperaturas extremas.

En áreas ecuatoriales la ausencia de estaciones térmicas y la poca variación de las temperaturas a lo largo del año hacen que la amplitud térmica anual sea muy baja, por lo que es más díficil calcular en estos territorios los efectos de la continentalidad/oceaneidad.

Los índices más empleados para expresar la continentalidad/oceanidad se pueden agrupar en sencillos y compensados. Son sencillos aquellos que expresan únicamente la diferencia entre las temperaturas extremas (Supan, 1884), y compensados los que, a la amplitud u oscilación de la temperatura anual, se adiciona una cantidad en función de la altitud (Rivas Martínez, 2005) o de la latitud (Gorezynski, 1920; Conrad, 1946; Currey, 1974).

Índice Umbrales o categorías comunes Comentarios
Índice de Supan No tiene umbrales estándar claros, es más una medida continua Se interpreta en función de valores relativos
Índice de Conrad A veces se usa con límites aproximados para continentalidad Sin categoría oficial estricta
Índice de Kerner Pocas categorías definidas oficialmente Uso más descriptivo
Índice de Schulze No tiene categorías ampliamente establecidas Índice de variabilidad térmica
Índice de Currey Se han sugerido rangos para diferenciar climas oceánicos y continentales, pero no universales Variable según zona
Índice de Gorezynski Sí, a menudo tiene categorías definidas: Ejemplo aproximado (según algunas fuentes):
- < 25: clima oceánico
- 25 - 40: subcontinental
- > 40: continental
Índice de Rivas-Martínez Sí, tiene rangos para clasificar la continentalidad Muy usado en biogeografía española
Índice de Daget Tiene categorías, adaptadas de Conrad con altitud Similar a Conrad, pero con ajuste por altitud
Índice de Johansson (K) Sí, se han propuesto categorías:
- < 10: clima oceánico
- 10 - 20: clima suboceánico
- 20 - 30: subcontinental
- > 30: continental

ACTIVACIÓN DE LOS PAQUETES NECESARIOS Y DESCARGA DE LA INFORMACIÓN

library(dplyr)
## Warning: package 'dplyr' was built under R version 4.3.2
## 
## 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
library(ggplot2)
library(GSODR)
library(lubridate)
## Warning: package 'lubridate' was built under R version 4.3.3
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union

Descarga de las estaciones meteorologicas seleccionadas

estaciones <- c("726060-14764", "080010-99999")
gsod_diarios <- get_GSOD(years = 1991:2020, station = estaciones) %>%
  select(STNID, LATITUDE, ELEVATION, YEARMODA, YEAR, MONTH, DAY, YDAY, TEMP, MAX, MIN) %>%
  rename(wmo = STNID, latitud = LATITUDE, altitud = ELEVATION, date = YEARMODA, yy = YEAR, mm = MONTH, dd = DAY, jul = YDAY, tm = TEMP, tx = MAX, tn = MIN) %>%
  mutate(date = ymd(date))  
gsod_diarios
##                 wmo latitud altitud       date    yy    mm    dd   jul    tm
##              <char>   <num>   <num>     <Date> <int> <int> <int> <int> <num>
##     1: 080010-99999  43.367    67.0 1991-01-01  1991     1     1     1  10.3
##     2: 080010-99999  43.367    67.0 1991-01-02  1991     1     2     2  12.8
##     3: 080010-99999  43.367    67.0 1991-01-03  1991     1     3     3  11.9
##     4: 080010-99999  43.367    67.0 1991-01-04  1991     1     4     4   9.3
##     5: 080010-99999  43.367    67.0 1991-01-05  1991     1     5     5  11.9
##    ---                                                                      
## 21866: 726060-14764  43.642    13.5 2020-12-27  2020    12    27   362  -0.9
## 21867: 726060-14764  43.642    13.5 2020-12-28  2020    12    28   363   0.2
## 21868: 726060-14764  43.642    13.5 2020-12-29  2020    12    29   364   0.7
## 21869: 726060-14764  43.642    13.5 2020-12-30  2020    12    30   365  -4.6
## 21870: 726060-14764  43.642    13.5 2020-12-31  2020    12    31   366   3.4
##           tx    tn
##        <num> <num>
##     1:  13.0   7.6
##     2:  14.0  11.6
##     3:  14.2   9.8
##     4:  12.0   7.4
##     5:  13.0   9.2
##    ---            
## 21866:   8.3  -3.9
## 21867:   7.2  -6.1
## 21868:   7.2  -6.7
## 21869:   5.0  -8.9
## 21870:   6.1   1.1
rm(estaciones)

Etiquetas de meses en español

meses <- c("Ene", "Feb", "Mar", "Abr", "May", "Jun","Jul", "Ago", "Sep", "Oct", "Nov", "Dic")

# Asegurarse de que los meses están bien ordenados
gsod_diarios$mm <- factor(gsod_diarios$mm, 
                             levels = 1:12, 
                             labels = meses, 
                             ordered = TRUE)
rm(meses)

Convertir wmo en un factor

gsod_diarios <- gsod_diarios %>%
  mutate(wmo = as.factor(wmo))

Obtención de los valores normales

df_normales <- gsod_diarios %>%
  group_by(wmo, mm) %>%
  summarise(
    latitud = mean(latitud, na.rm = TRUE),
    altitud = mean(altitud, na.rm = TRUE),
    tx_abs = max(tx, na.rm = TRUE),                      # Máxima absoluta
    tn_abs = min(tn, na.rm = TRUE),                      # Mínima absoluta
    tx = mean(tx, na.rm = TRUE),                   # Media de las máximas diarias
    tn = mean(tn, na.rm = TRUE),                   # Media de las mínimas diarias
    tm = mean(tm, na.rm = TRUE),                   # Media mensual (promedio de todos los días)
    .groups = "drop")
df_normales
## # A tibble: 24 × 9
##    wmo          mm    latitud altitud tx_abs tn_abs    tx    tn    tm
##    <fct>        <ord>   <dbl>   <dbl>  <dbl>  <dbl> <dbl> <dbl> <dbl>
##  1 080010-99999 Ene      43.4      67   21     -5    13.5  8.56  10.8
##  2 080010-99999 Feb      43.4      67   24.6   -1.9  14.1  8.41  10.9
##  3 080010-99999 Mar      43.4      67   27.5   -0.8  15.6  9.45  12.1
##  4 080010-99999 Abr      43.4      67   31.6    3.5  16.5 10.3   12.9
##  5 080010-99999 May      43.4      67   33.5    0.1  18.6 12.4   15.0
##  6 080010-99999 Jun      43.4      67   34.4    9    20.8 14.6   17.2
##  7 080010-99999 Jul      43.4      67   34.4   10.2  22.3 16.2   18.8
##  8 080010-99999 Ago      43.4      67   35.2    7.4  23.1 16.7   19.4
##  9 080010-99999 Sep      43.4      67   35.4    5    22.1 15.5   18.2
## 10 080010-99999 Oct      43.4      67   31.5    6    19.5 13.5   16.1
## # ℹ 14 more rows
#rm(gsod_diarios)

Se graba el material descargado

save.image("D:/G167_CLIMATOLOGIA_2026/2_EJERCICIOS_PRACTICOS/1_MODULO_2_TEMA_5_Temperatura/mis_estaciones_valores_normales_1991_2020.RData")
# En caso de necesitar cargarlos otra vez load("datos_analisis_representacion_temperatura")

ÍNDICES DE CONTINENTALIDAD SENCILLOS

Se basan en el análisis de la amplitud térmica (diferencia entre el mes más cálido y el más frío), compensados en ocasiones por la latitud o por la altitud

Fundamentos teóricos:

Índice En qué se basa
Supan Amplitud térmica anual
Conrad Amplitud térmica ajustada por sin(lat + 10)
Kerner (T_abr + T_oct) / amplitud térmica
Schulze Desviación mensual respecto a la media anual
Currey Amplitud térmica / (lat / 3 + 1)
Gorezynski Amplitud térmica ajustada por sin(lat)

\[Ic = T_{max} - T_{min}\]

donde Tmax⁡T_{}Tmax es la temperatura media del mes más cálido y Tmin⁡T_{}Tmin la del mes más frío.

supan <- df_normales %>%
  group_by(wmo) %>%
  summarise(
    Tm_max = max(tm, na.rm = TRUE),
    Tm_min = min(tm, na.rm = TRUE),
    supan = Tm_max - Tm_min,
    .groups = "drop"
  )

ggplot(supan, aes(x = factor(wmo), y = supan)) +
  geom_col(fill = "steelblue", color = "black", width = 0.6) +  # barras más estrechas y borde negro
  labs(title = "Índice de Supan por Estación",
       x = "ID",
       y = "Índice de Supan (°C)") +
  theme_minimal() +
  theme(
    axis.text.x = element_text(angle = 0, hjust = 0.5, size = 14, face = "bold", color = "black"),  # eje X, texto negro, grande y negrita
    axis.text.y = element_text(size = 14, face = "bold", color = "black")                           # eje Y, texto negro, grande y negrita
  )

\[K = \frac{T_{oct} - T_{apr}}{A} \times 100\]

donde:

\({T_{oct}\) = Temperatura media de octubre;

\(T_{apr}\) Temperatura media de abril;

\({A}\) = Amplitud térmica anual (diferencia entre las medias del mes más cálido y el mes más frío)

Interpretación:

Valor Categoría
< 0.1 clima muy oceánico
0.1–0.3 clima oceánico moderado
0.3–0.5 clima semicontinental
>0.5 clima continental
kerner <- df_normales %>%
  group_by(wmo) %>%
  summarise(
    T_abr = tm[mm == "Abr"][1],
    T_oct = tm[mm == "Oct"][1],
    Tm_max = max(tm, na.rm = TRUE),
    Tm_min = min(tm, na.rm = TRUE),
    KOI = (T_abr + T_oct) / (Tm_max - Tm_min),
    .groups = "drop"
  )
ggplot(kerner, aes(x = factor(wmo), y = KOI)) +
  geom_col(fill = "steelblue", color = "black", width = 0.6) +  # barras más estrechas y borde negro
  labs(title = "Índice de Supan por Estación",
       x = "ID",
       y = "Índice de Oceanidad de Kerner (°C)") +
  theme_minimal() +
  theme(
    axis.text.x = element_text(angle = 0, hjust = 0.5, size = 14, face = "bold", color = "black"),  # eje X, texto negro, grande y negrita
    axis.text.y = element_text(size = 14, face = "bold", color = "black")                           # eje Y, texto negro, grande y negrita
  )

\[Ic_S = 100 \times \frac{\sum_{i=1}^{12} |T_i - \overline{T}|}{\overline{T}} \]

donde

\(\overline{T}\) es la temperatura media anual

\(T_i\) las medias mensuales.

Se suman las desviaciones absolutas mensuales respecto a la media anual. Para ello, primero se agrupan por wmo, se calcula la media anual para cada estación, y luego sumar las desviaciones absolutas mensuales.

schulze <- df_normales %>%
  group_by(wmo) %>%
  mutate(
    T_anual = mean(tm, na.rm = TRUE)) %>%
  summarise(
    IcS = 100 * sum(abs(tm - T_anual), na.rm = TRUE) / T_anual[1],
    .groups = "drop"
  )

Índices de continentalidad compensados por la latitud

Entre los índices que no sólo tienen en cuenta la amplitud térmica, sino también la latitud (puesto que es un factor que influye en el gradiente de temperatura) caben destacar los índices de Gorezynski (1920), Conrad (1946) y Currey (1974).

  • Índice de Gorezynski (1920) asegura que la continentalidad queda compensada con la latitud mediante la fórmula:

\[I_{cg} = \frac{1.7 (M_i - m_i)}{\sin(\text{Lat})} - 20.4 \]

donde

\(M_i\) = Temperaturas medias del mes más cálido (°C).

\(m_i\) = Temperaturas medias del mes más frío (°C).

\(Lat\) = latitud en grados.

A diferencia del índice de Conrad, aquí no se suma 10 a la latitud: se usa la latitud directamente en la función sin().

gorezynski <- df_normales %>%
  group_by(wmo) %>%
  summarise(
    lat = abs(first(latitud)),
    Tm_max = max(tm, na.rm = TRUE),
    Tm_min = min(tm, na.rm = TRUE),
    icg = (1.7 * (Tm_max - Tm_min)) / sin(lat * pi / 180) - 20.4,
    .groups = "drop"
  )

Índice de Conrad (1946)

Es similar al anterior, pero Conrad ajusta la fórmula para que los valores resultantes varían entre cero (extremadamente oceánico para las Islas Feroes) y 100 (extremadamente continental para Verchojansk, en el nordeste de Siberia).

\[Icc = \frac{1.7 (M_i - m_i)}{\sin(\text{Lat} + 10)} - 14\]

en donde

\(M_i\) = Temperaturas medias del mes más cálido (°C).

\(m_i\) = Temperaturas medias del mes más frío (°C).

\(Lat\) = latitud en grados (hay que convertir a radianes antes de aplicar sin() en R).

\[\text{lat_rad} = (\text{Lat} + 10) \cdot \frac{\pi}{180}\]

conrad <- df_normales %>%
  group_by(wmo) %>%
  summarise(
    latitud = first(abs(latitud)),
    Tm_max = max(tm, na.rm = TRUE),
    Tm_min = min(tm, na.rm = TRUE),
    icc = (1.7 * (Tm_max - Tm_min)) / sin((latitud + 10) * pi / 180) - 14,
    .groups = "drop")

Cuando la latitud es mayor a 80º el sen (Lat+10) se considera igual a 1. Tabla de correspondencia de los valores del índice de Conrad. Fuente: Rivas Martínez (2005).

IC Categoría
-20 a 20 Hiperoceánicos
20 a 40 Oceánicos
40 a 60 Subcontinentales
60 a 80 Continentales
80 a 120 Hipercontinentales
  • Índice de continentalidad de Currey (1974), se obtiene dividiendo la amplitud térmica anual (o diferencia entre la temperatura media de los meses más cálido y más frío del año) entre el tercio de la latitud más uno. Por lo tanto su fórmula es:

\[IC_{Currey} = \frac{M_i - m_i}{1 + \tfrac{1}{3}\,\text{Lat}} \]

en donde

\(M_i\) = Temperaturas medias del mes más cálido (°C).

\(m_i\) = Temperaturas medias del mes más frío (°C).

\(Lat\) = latitud en grados (sin signo).

currey <- df_normales %>%
  group_by(wmo) %>%
  summarise(
    lat = abs(first(latitud)),
    Tm_max = max(tm, na.rm = TRUE),
    Tm_min = min(tm, na.rm = TRUE),
    currey = (Tm_max - Tm_min) / ((lat / 3) + 1),
    .groups = "drop"
  )

Tabla de correspondencia de los valores del índice de Currey. Fuente: Rivas Martínez (2005).

ICurrey Categoría
0 a 0,6 Hiperoceánicos
0,6 a 1,1 Oceánicos
1,1 a 1,7 Subcontinentales
1,7 a 2,3 Continentales
2,3 a 5 Hipercontinentales
  • Índice de continentalidad de Johansson

\[K = 1.7 \cdot \frac{T_{\text{max}} - T_{\text{min}}}{\sin(\varphi + 10^\circ)} - 20.4\]

donde:

\(T_max\) = Temperaturas medias del mes más cálido (°C).

\(T_min\) = Temperaturas medias del mes más frío (°C).

\(\varphi\) = latitud en grados decimales (positiva en el hemisferio norte, negativa en el sur), debe transformarse en radianes en el caso de R

johansson <- df_normales %>%
  group_by(wmo) %>%
  summarise(
    lat = abs(first(latitud)),
    Tm_max = max(tm, na.rm = TRUE),
    Tm_min = min(tm, na.rm = TRUE),
    K = 1.7 * (Tm_max - Tm_min) / sin((lat + 10) * pi / 180) - 20.4,
    .groups = "drop"
  )
KJ Tipo de clima
< 5 Clima oceánico extremo (hiper-oceánico)
5 – 15 Clima oceánico o marítimo
15 – 25 Clima subcontinental o semicontinental
25 – 40 Clima continental
> 40 Clima fuertemente continental o extremo

Clasificación según el índice de Johansson

Índices de continentalidad compensados por altitud

Estos índices valoran la continentalidad de un territorio teniendo en cuenta la altitud. Destaca el índice de continentalidad de Rivas-Martínez.

  • Índice de continentalidad Rivas-Martínez (2005): este cálculo tiene en cuenta el índice de continentalidad simple y la altitud. Su fórmula es:

\[IC_{Rm} = IC_{simple} + \frac{\text{altitud} \times 0.6}{100} \]

en donde,

\(altitud\) se mide en metros.

johansson <- df_normales %>%
  group_by(wmo) %>%
  summarise(
    alt = first(altitud),
    Tm_max = max(tm, na.rm = TRUE),
    Tm_min = min(tm, na.rm = TRUE),
    icrm = (Tm_max - Tm_min) + ((0.6 * alt) / 100),
    .groups = "drop"
  )

A igualdad de latitud, los valores del índice aumentan con la altitud, lo que tiene sentido ecológico: cuanto más alto, mayor aislamiento térmico → mayor continentalidad.

Índices de continentalidad compensados por latitud y altitud

  • Índice de Daget (1977) este índice es el más completo puesto que tiene en cuenta las temperaturas, la latitud y la altitud. Su fórmula es:

\[IC_{Daget} = \frac{1.7 \, am}{\sin(\text{lat} + 10 + 9h)} - 14 \]

en donde:

\(am\) = amplitud térmica

\(lat\) = latitud (en grados)

\(h\) = altura (en Km)

daget <- df_normales %>%
  group_by(wmo) %>%
  summarise(
    Tm_max = max(tm, na.rm = TRUE),
    Tm_min = min(tm, na.rm = TRUE),
    a_m = Tm_max - Tm_min,
    lat = abs(first(latitud)),
    h = first(altitud) / 1000,
    daget = (1.7 * a_m) / sin((lat + 10 + 9 * h) * pi / 180) - 14,
    .groups = "drop"
  )

Crear un dataframe con los resultados

cuadro_final <- as.data.frame(cbind(supan$wmo, supan$supan))
cuadro_final <- cuadro_final %>% rename(wmo = V1, supan = V2)
cuadro_final$Kerner <- kerner$KOI
cuadro_final$Schulze <- schulze$IcS
cuadro_final$Conrad <-conrad$icc
cuadro_final$Currey <-currey$currey
cuadro_final$Gorezynski <-gorezynski$icg
cuadro_final$Johansson <- johansson$icrm
cuadro_final$Daget <- daget$daget

*️⃣ APLICA LAS SIGUIENTES PREGUNTAS A TU TRABAJO PRÁCTICO SOBRE LAS DOS ESTACIONES SELECCIONADAS