Lectura de datos y librerias

Vamos a leer las librerias necesarias para seguir con el análisis de datos y las bases sobre las que vamos a trabajar.

Muestra de datos

Se muestran los datos originales sobre los que vamos a trabajar.

Análisis de calidad

Descarte de variables

Antes de empezar con el análisis de datos ya sabemos que vamos a descartar unas variables de la base de datos que no interesan como son: DATAFLOW, LAST_UPDATE, freq, unit, OBS_FLAG y CONF_STATUS

Tipo de variables

Describimos de qué tipo son las variables de cada base de datos

Lo mostramos en estas tablas:

Análisis Exploratorio

Distribución de valores

Se analizan las variables numéricas de ambas bases de datos con las variables ya seleccionadas.( Se empieza con el resumen básico que muestra la distribución de los datos (media, mediana, cuartiles…)
Variables numéricas de IE:

Para IE, solo tenemos dos variables numéricas que son el periodo de tiempo y el OBS_VALUE que indica el valor de la transacción. Vemos que tenemos valores faltantes en el valor de las transacciones. Observando que el valor de la media es superior al tercer cuartil, deducimos que la distribución de las transacciones están sesgadas a la izquierda (más transacciones de menor valor), para comprobarlo vamos a realizar un gráfico box and whisker y un histograma:

Analizando las gráficas se confirman las observaciones.

Variables Numéricas de PIB:

Observando los valores de la media y del tercer cuartil vemos que se repite el mismo fenómeno en ambas bases de datos, cuanto mayor es el valor de la transacción, menor es la frecuencia, es decir, está sesgada a la izquierda, con más cantidad de datos de menor valor. Lo vamos a comprobar con un box and whisker y un histograma:  

Se confirman las observaciones con ambas gráficas que muestran una mayor frecuencia de los datos cuando las transacciones son de menor valor.

Valores Faltantes

Vamos a observar los valores faltantes de la base de datos IE por cada variable tanto en cantidad como en porcentaje sobre el total.

Observamos que solo hay valores faltantes en la variable obs_value, en concreto 320, que es un 0.44% sobre el total. Como la variable que queremos estudiar es esta, no nos interesa mantener las observaciones sobre las cuales no tenemos esa información, más adelante tras analizar la base de datos PIB, eliminaremos aquellas observaciones en las que no se tenga información en la variable OBS_VALUE.
Ahora vamos a observar los valores faltantes de la base de datos PIB:

En esta base de datos encontramos 6309 casos faltantes únicamente en la variable OBS_VALUE, aunque pueda parecer una cantidad excesiva es únicamente el 0.81 % del total, como se repite la situación en la que es esta la variable que queremos estudiar, vamos a eliminar aquellas observaciones en las que no se tenga esta información.

Eliminación Valores Faltantes

Partiendo de que no nos interesan aquellas filas en las que falte aparezcan valores faltantes, debido a que la carencia de información en alguna de todas las variables, la observación no nos sirve. Se eliminan todas las filas en las que falte cualquier tipo de información.

Indices de Libertad

Lecutra de datos

Base de datos independiente de las anteriores que añadiremos al estudio para correlacionar las políticas del país con su rendimiento económico. A esta base de datos le sustituiremos los valores nulos por 0, no eliminaremos información de paises por los valores faltantes.

Se muestra la base de datos original:

Tratado valores faltantes

Se añaden 0 a los valores faltantes, y mostramos la cabecera del resultado.

Exportación Bases de Datos

Antes de seguir con el estudio, se guarda la base de datos modificada con la que se sigue en formato xlsx.

Commodities

Se vuelve a cambiar de base de datos y ahora trataremos la que muestra los datos de exportación e importación de cada país. La utilizaremos para comprobar si el índice de libertad, y el PIB tiene relación con el nivel de importaciones y exportaciones.

Lectura de Bases de datos

Se empieza con la lectura de las bases de datos.

Tratado de variables

Se empieza a borrar aquellas variables que tenemos claro que queremos descartar, que son: ‘comm_code’, ‘quantity_name’, ‘quantity’ y ‘flow’.

Filtrado de casos

De la información otorgada por esta base de datos, solo nos informa de cada país por específico, por eso eliminamos los casos de ‘EU-28’, y el de la suma de todos las commodities ‘ALL COMMODITIES’.

OBJETIVO 1:

• Evaluar la correlación entre los países importadores y exportadores de estos productos clave, buscando patrones de dependencia y relaciones comerciales significativas

Este gráfico muestra cómo se relacionan los valores de exportación entre diferentes países a lo largo del tiempo. Para ello, calculamos la correlación entre las series anuales de exportaciones de cada país.

A simple vista, la mayoría de las correlaciones son altas, lo que podría indicar que todos los países exportan de manera parecida. Sin embargo, esta semejanza no significa necesariamente que los países estén conectados comercialmente, sino que todos han seguido una tendencia general de crecimiento en el comercio internacional, especialmente desde los años 90

library(factoextra)

# Dendrograma_cruzado_de exportadores con factoextra
fviz_dend(hc_exp, 
          k = 4, 
          cex = 0.6, 
          lwd = 0.8, 
          k_colors = c("#D73027", "#4575B4", "#1A9850", "#FDAE61"),  # Colores suaves
          rect = TRUE, 
          rect_border = "white", 
          rect_fill = TRUE,
          main = "Dendrograma cruzado: Exportadores (correlación con importadores)")

# Dendrograma cruzado de importadores con factoextra
fviz_dend(hc_imp, 
          k = 4, 
          cex = 0.6, 
          lwd = 0.8, 
          k_colors = c("#D73027", "#4575B4", "#1A9850", "#FDAE61"),
          rect = TRUE, 
          rect_border = "white", 
          rect_fill = TRUE,
          main = "Dendrograma cruzado: Importadores (correlación con exportadores)")

# Unir cluster cruzado a los datos
COMEXP_cruzado <- COMEXP_summary_clustered %>%
  left_join(df_clusters_exp_cross, by = c("country_or_area" = "Exportador"))

# Renombrar para trabajar limpio
COMEXP_cruzado <- COMEXP_cruzado %>%
  rename(Cluster_Exportador = Cluster_Exportador.y)

# Evolución media por cluster (exportadores cruzados)
COMEXP_cruzado %>%
  group_by(year, Cluster_Exportador) %>%
  summarise(media_export = mean(trade_usd, na.rm = TRUE), .groups = "drop") %>%
  ggplot(aes(x = year, y = media_export, color = factor(Cluster_Exportador))) +
  geom_line(size = 1.2) +
  labs(title = "Evolución promedio de exportaciones (cluster cruzado)",
       y = "Exportaciones promedio (USD)", x = "Año", color = "Cluster cruzado") +
  theme_minimal(base_size = 12)

# Boxplot por cluster cruzado
COMEXP_cruzado %>%
  ggplot(aes(x = factor(Cluster_Exportador), y = trade_usd)) +
  geom_boxplot(fill = "lightblue") +
  scale_y_log10() +
  labs(title = "Distribución de exportaciones (cluster cruzado)",
       x = "Cluster cruzado", y = "Exportaciones (escala log)") +
  theme_minimal(base_size = 12)

# Tabla resumen exportadores
resumen_clusters_export <- COMEXP_cruzado %>%
  group_by(Cluster_Exportador, country_or_area) %>%
  summarise(total_promedio = mean(trade_usd, na.rm = TRUE), .groups = "drop") %>%
  group_by(Cluster_Exportador) %>%
  summarise(
    `Nº de países` = n(),
    `Media (USD)` = round(mean(total_promedio, na.rm = TRUE)),
    `Mínimo (USD)` = round(min(total_promedio, na.rm = TRUE)),
    `Máximo (USD)` = round(max(total_promedio, na.rm = TRUE)),
    `Desviación estándar` = round(sd(total_promedio, na.rm = TRUE))
  )

print(resumen_clusters_export)
## # A tibble: 4 × 6
##   Cluster_Exportador `Nº de países` `Media (USD)` `Mínimo (USD)` `Máximo (USD)`
##                <int>          <int>         <dbl>          <dbl>          <dbl>
## 1                  1             14    4989925471       31224456    63232197397
## 2                  2             20     250679447       37059409      946595926
## 3                  3             11     399591711       15704803     1132202758
## 4                  4              9     393447535       36492532     1178913776
## # ℹ 1 more variable: `Desviación estándar` <dbl>
cat("\n📌 Conclusión exportadores:\n")
## 
## 📌 Conclusión exportadores:
cat("El análisis agrupó a los países exportadores en 4 clusters cruzados según su relación con importadores.\n\n")
## El análisis agrupó a los países exportadores en 4 clusters cruzados según su relación con importadores.
cat("• El cluster con mayor volumen medio es el ", 
    resumen_clusters_export$Cluster_Exportador[which.max(resumen_clusters_export$`Media (USD)`)], 
    " con ", 
    format(resumen_clusters_export$`Media (USD)`[which.max(resumen_clusters_export$`Media (USD)`)], big.mark = ","), 
    " USD de media.\n", sep="")
## • El cluster con mayor volumen medio es el 1 con 4,989,925,471 USD de media.
cat("• El cluster más bajo es el ", 
    resumen_clusters_export$Cluster_Exportador[which.min(resumen_clusters_export$`Media (USD)`)], 
    ", reflejando países con baja presencia exportadora.\n", sep="")
## • El cluster más bajo es el 2, reflejando países con baja presencia exportadora.
cat("• La desviación estándar muestra cuán homogéneos o diversos son los países dentro de cada grupo.\n")
## • La desviación estándar muestra cuán homogéneos o diversos son los países dentro de cada grupo.
# Unir cluster cruzado a los datos
COMIMP_cruzado <- COMIMP_summary_clustered %>%
  left_join(df_clusters_imp_cross, by = c("country_or_area" = "Importador"))

# Renombrar limpio
COMIMP_cruzado <- COMIMP_cruzado %>%
  rename(Cluster_Importador = Cluster_Importador.y)

# Evolución media por cluster (importadores cruzados)
COMIMP_cruzado %>%
  group_by(year, Cluster_Importador) %>%
  summarise(media_import = mean(total_import, na.rm = TRUE), .groups = "drop") %>%
  ggplot(aes(x = year, y = media_import, color = factor(Cluster_Importador))) +
  geom_line(size = 1.2) +
  labs(title = "Evolución promedio de importaciones (cluster cruzado)",
       y = "Importaciones promedio (USD)", x = "Año", color = "Cluster cruzado") +
  theme_minimal(base_size = 12)

# Boxplot por cluster cruzado
COMIMP_cruzado %>%
  ggplot(aes(x = factor(Cluster_Importador), y = total_import)) +
  geom_boxplot(fill = "lightgreen") +
  scale_y_log10() +
  labs(title = "Distribución de importaciones (cluster cruzado)",
       x = "Cluster cruzado", y = "Importaciones (escala log)") +
  theme_minimal(base_size = 12)

# Tabla resumen importadores
resumen_clusters_import <- COMIMP_cruzado %>%
  group_by(Cluster_Importador, country_or_area) %>%
  summarise(total_promedio = mean(total_import, na.rm = TRUE), .groups = "drop") %>%
  group_by(Cluster_Importador) %>%
  summarise(
    `Nº de países` = n(),
    `Media (USD)` = round(mean(total_promedio, na.rm = TRUE)),
    `Mínimo (USD)` = round(min(total_promedio, na.rm = TRUE)),
    `Máximo (USD)` = round(max(total_promedio, na.rm = TRUE)),
    `Desviación estándar` = round(sd(total_promedio, na.rm = TRUE))
  )

print(resumen_clusters_import)
## # A tibble: 4 × 6
##   Cluster_Importador `Nº de países` `Media (USD)` `Mínimo (USD)` `Máximo (USD)`
##                <int>          <int>         <dbl>          <dbl>          <dbl>
## 1                  1             15  495889199048    46502083394  1624033632052
## 2                  2             12  159709735835    35658798393   413521839657
## 3                  3             20  447042464610    38473112570  2329871358662
## 4                  4              8  182773877149    28967688292   530546501882
## # ℹ 1 more variable: `Desviación estándar` <dbl>
cat("\n📌 Conclusión importadores:\n")
## 
## 📌 Conclusión importadores:
cat("El análisis agrupó a los países importadores en 4 clusters cruzados según su relación con exportadores.\n\n")
## El análisis agrupó a los países importadores en 4 clusters cruzados según su relación con exportadores.
cat("• El cluster con mayor volumen medio es el ", 
    resumen_clusters_import$Cluster_Importador[which.max(resumen_clusters_import$`Media (USD)`)], 
    " con ", 
    format(resumen_clusters_import$`Media (USD)`[which.max(resumen_clusters_import$`Media (USD)`)], big.mark = ","), 
    " USD de media.\n", sep="")
## • El cluster con mayor volumen medio es el 1 con 495,889,199,048 USD de media.
cat("• El cluster más bajo es el ", 
    resumen_clusters_import$Cluster_Importador[which.min(resumen_clusters_import$`Media (USD)`)], 
    ", reflejando países con menor peso en el comercio internacional.\n", sep="")
## • El cluster más bajo es el 2, reflejando países con menor peso en el comercio internacional.
cat("• La desviación estándar ayuda a evaluar la homogeneidad dentro de cada cluster.\n")
## • La desviación estándar ayuda a evaluar la homogeneidad dentro de cada cluster.
# === Librerías necesarias ===
library(dplyr)
library(ggplot2)
library(factoextra)

# === Paso 1: Calcular promedios totales por país ===

# Promedio exportaciones
prom_export <- COMEXP_summary %>%
  group_by(country_or_area) %>%
  summarise(media_export = mean(trade_usd, na.rm = TRUE))

# Promedio importaciones
prom_import <- COMIMP_summary %>%
  group_by(country_or_area) %>%
  summarise(media_import = mean(total_import, na.rm = TRUE))

# Unión de ambas
datos_promedios <- as.data.frame(inner_join(prom_export, prom_import, by = "country_or_area"))
rownames(datos_promedios) <- datos_promedios$country_or_area

# === Paso 2: Clustering jerárquico ===
datos_promedios_scaled <- scale(datos_promedios[, c("media_export", "media_import")])
dist_promedios <- dist(datos_promedios_scaled)
hc_promedios <- hclust(dist_promedios, method = "ward.D2")

# Asignar clusters y convertir a factor
datos_promedios$Cluster_Promedio <- factor(cutree(hc_promedios, k = 4), levels = 1:4)

# === Paso 3: Definir paleta fija de colores para ambos gráficos ===
colores_fijos <- c(
  "4" = "#984EA3",  # morado
  "1" = "#E41A1C",  # rojo
  "3" = "#4DAF4A",  # verde
  "2" = "#377EB8"   # azul
)

# === Paso 4: Dendrograma con colores fijos ===
fviz_dend(hc_promedios, k = 4, rect = TRUE,
          main = "Dendrograma - Clustering por promedios",
          k_colors = colores_fijos,
          cex = 0.7)

# === Paso 5: Gráfico de dispersión con los mismos colores ===
ggplot(datos_promedios, aes(x = media_import, y = media_export, color = Cluster_Promedio)) +
  geom_point(size = 3) +
  scale_color_manual(values = colores_fijos) +
  labs(title = "Clustering cruzado (Promedios totales)",
       x = "Importaciones medias (USD)",
       y = "Exportaciones medias (USD)",
       color = "Cluster") +
  theme_minimal()

# === Paso 6: Tabla resumen por cluster ===
resumen_clusters_cross <- datos_promedios %>%
  group_by(Cluster_Promedio) %>%
  summarise(
    `Nº de países` = n(),
    `Media Export (USD)` = round(mean(media_export, na.rm = TRUE)),
    `Media Import (USD)` = round(mean(media_import, na.rm = TRUE)),
    `Ratio Exp/Imp` = round(mean(media_export / media_import, na.rm = TRUE), 2),
    `Desviación total` = round(sd(rowMeans(cbind(media_export, media_import)), na.rm = TRUE))
  )

print(resumen_clusters_cross)
## # A tibble: 4 × 6
##   Cluster_Promedio `Nº de países` `Media Export (USD)` `Media Import (USD)`
##   <fct>                     <int>                <dbl>                <dbl>
## 1 1                            57           1047505813         144808256584
## 2 2                            10            558111951         906406572191
## 3 3                             2           2285036742        2304894184045
## 4 4                             1          63232197397         323952942782
## # ℹ 2 more variables: `Ratio Exp/Imp` <dbl>, `Desviación total` <dbl>
# Librerías necesarias
library(dplyr)
library(tidyr)
library(ggplot2)
library(factoextra)

# === Paso 1: Calcular variaciones porcentuales anuales ===

# EXPORTACIONES
delta_export <- COMEXP %>%
  mutate(trade_usd = as.numeric(trade_usd),
         year = as.numeric(year)) %>%
  group_by(country_or_area) %>%
  arrange(year) %>%
  mutate(delta = (trade_usd - lag(trade_usd)) / lag(trade_usd)) %>%
  filter(!is.na(delta)) %>%
  summarise(var_export = mean(delta, na.rm = TRUE), .groups = "drop")

# IMPORTACIONES
delta_import <- COMIMP %>%
  mutate(trade_usd = as.numeric(trade_usd),
         year = as.numeric(year)) %>%
  group_by(country_or_area) %>%
  arrange(year) %>%
  mutate(delta = (trade_usd - lag(trade_usd)) / lag(trade_usd)) %>%
  filter(!is.na(delta)) %>%
  summarise(var_import = mean(delta, na.rm = TRUE), .groups = "drop")

# === Paso 2: Unión y clustering jerárquico ===
datos_var <- inner_join(delta_export, delta_import, by = "country_or_area")
rownames(datos_var) <- datos_var$country_or_area

# Escalar y clusterizar
datos_var_scaled <- scale(datos_var[, c("var_export", "var_import")])
dist_var <- dist(datos_var_scaled)
hc_var <- hclust(dist_var, method = "ward.D2")

# ✅ Convertir en dendrograma CON ETIQUETAS DE PAÍSES
dend_var <- as.dendrogram(hc_var)
labels(dend_var) <- rownames(datos_var)[order.dendrogram(dend_var)]

# Añadir clusters
datos_var$Cluster_Variacion <- factor(cutree(hc_var, k = 4), levels = 1:4)

# === Paso 3: Paleta fija de colores
colores_fijos <- c("1" = "#984EA3", "2" = "#E41A1C", "3" = "#4DAF4A", "4" = "#377EB8")

# === Paso 4: Dendrograma con nombres de países
fviz_dend(dend_var, k = 4, rect = TRUE,
          main = "Dendrograma - Clustering por variación anual",
          k_colors = colores_fijos,
          cex = 0.65)

# === Paso 5: Dispersión export/import
ggplot(datos_var, aes(x = var_import, y = var_export, color = Cluster_Variacion)) +
  geom_point(size = 3) +
  scale_color_manual(values = colores_fijos) +
  labs(title = "Clustering cruzado (Variación anual promedio)",
       x = "Importaciones (% promedio anual)",
       y = "Exportaciones (% promedio anual)",
       color = "Cluster") +
  theme_minimal()

# === Paso 6: Tabla resumen
resumen_clusters_var <- datos_var %>%
  group_by(Cluster_Variacion) %>%
  summarise(
    `Nº de países` = n(),
    `Media Var. Export` = round(mean(var_export, na.rm = TRUE), 3),
    `Media Var. Import` = round(mean(var_import, na.rm = TRUE), 3),
    `Ratio Var Exp/Imp` = round(mean(var_export / var_import, na.rm = TRUE), 2),
    `Desviación total` = round(sd(rowMeans(cbind(var_export, var_import)), na.rm = TRUE))
  )
print(resumen_clusters_cross)
## # A tibble: 4 × 6
##   Cluster_Promedio `Nº de países` `Media Export (USD)` `Media Import (USD)`
##   <fct>                     <int>                <dbl>                <dbl>
## 1 1                            57           1047505813         144808256584
## 2 2                            10            558111951         906406572191
## 3 3                             2           2285036742        2304894184045
## 4 4                             1          63232197397         323952942782
## # ℹ 2 more variables: `Ratio Exp/Imp` <dbl>, `Desviación total` <dbl>