Evaluacion Tecnica

Proyecto: Comercio Internacional

Cargar Librerias Necesarias

library(readxl)
library(dplyr)
library(corrplot)
library(leaflet)
library(rnaturalearth)
library(sf)
library(tidyverse)
library(FactoMineR)
library(factoextra)
library(ggplot2)
library(shiny)
library(dendextend)

Cargar Datos

# Cargar los datos
Data_Geo <- read_excel("datos_geograficos.xlsx", col_types = 'text') 
commodities <- read_excel("Copia de commodity_IE.xlsx", col_types = 'text')
libertad_economica <- read_excel("libertad_economica.xlsx", col_types = "text")

Filtrar DataSet “commodities”

Para la elaboración del Objetivo II, de la BB.DD. de “commodities” unicamente necesitamos las columnas de “year”, “Pais” y “trade_usd”

commodities_filtrado <- commodities[, c("Pais", "year", "trade_usd")]

Agrupar por Pais y Año

Ahora necesitamos que todo este agrupado por pais y por año. De esta manera obtenemos la facturacion total de cada pais por año.

commodities_filtrado$trade_usd <- as.numeric(as.character(commodities_filtrado$trade_usd))

commodities_filtrado <- commodities_filtrado %>%
  group_by(Pais, year) %>%
  summarise(trade_usd = sum(trade_usd, na.rm = TRUE)) %>%
  ungroup()

Agregar Columna a “Data_Geo”

Añadimos una columna de 1 en caso de que el pais tenga acceso al mar y 0 en caso contrario. Esto lo realizamos de esta manera para poder hacer una correlacion con esta variable posteriormente.

Data_Geo$access_sea_bin <- ifelse(Data_Geo$`Access to Sea` == "Yes", 1, 0)

Unir las tablas

Ahora que ya tenemos las tablas arregladas para poder trabajar con ellas. Unimos las tres tablas en una. La union, la realizamos por Pais y por Año

# Paso 1: Unir con commodities_filtrado
libertad_geo_commodities <- inner_join(Data_Geo, commodities_filtrado, by = "Pais")

# Paso 2: Unir con libertad_economica (por País y year)
tabla_final <- inner_join(libertad_geo_commodities, libertad_economica, by = c("Pais", "year"))

Filtrar la tabla final

Volvemos a crear un filtro en la tabla final para poder manejar mejor las variables. Es decir, poder añadir y quitar variables segun si necesitamos evaluar esa variable o no. Esto se hace debido a que en la tabla_final hay 41 variables. Muchas pueden ser interantes para evaluar, pero en un inicio no necesitamos todas. Ademas a la vez que seleccionamos las variables que necesitamos, tambien convertimos a numerico las variables que estaban en character.

# Filtrar la tabla final y seleccionar solo las columnas específicas
tabla_filtrada <- tabla_final %>%
  select(Pais, ISO_code, year, `Geographical Particularity`, `ECONOMIC FREEDOM`,
         access_sea_bin, , trade_usd)

# Convertir las columnas Overall Score y trade_usd a numéricas
tabla_filtrada <- tabla_filtrada %>%
  mutate(
    trade_usd = as.numeric(trade_usd),
    `ECONOMIC FREEDOM` = as.numeric(`ECONOMIC FREEDOM`),
  )

# Verificar la estructura de los datos después del filtrado
summary(tabla_filtrada)
##      Pais             ISO_code             year          
##  Length:626         Length:626         Length:626        
##  Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character  
##                                                          
##                                                          
##                                                          
##  Geographical Particularity ECONOMIC FREEDOM access_sea_bin  
##  Length:626                 Min.   :3.320    Min.   :0.0000  
##  Class :character           1st Qu.:6.505    1st Qu.:1.0000  
##  Mode  :character           Median :7.235    Median :1.0000  
##                             Mean   :7.029    Mean   :0.9042  
##                             3rd Qu.:7.600    3rd Qu.:1.0000  
##                             Max.   :8.960    Max.   :1.0000  
##    trade_usd        
##  Min.   :1.208e+10  
##  1st Qu.:6.751e+10  
##  Median :1.527e+11  
##  Mean   :3.155e+11  
##  3rd Qu.:3.755e+11  
##  Max.   :3.203e+12

Procedemos a analizar con estadisticos y visualizaciones

Calcular correlacion

Primero calculamos la correlacion entre las variables de “economic_freedom”, “acces_sea_bin” y “trade_usd”. Seleccionamos estas variables para comprobar si la hipotesis inicial de que los paises con mayor libertad economica (con todos los aspectos, tanto politicos como comericiales que implica la libertad economica), y con acceso al mar tienen mayor valor en sus exportaciones.

# Filtrar tabla_final a solo las columnas necesarias
tabla_cor <- tabla_filtrada %>%
  select(`ECONOMIC FREEDOM`, access_sea_bin, trade_usd) 

# Calcular la matriz de correlación
cor_matrix <- cor(tabla_cor, use = "complete.obs")

# Mostrar la matriz de correlación
print(cor_matrix)
##                  ECONOMIC FREEDOM access_sea_bin trade_usd
## ECONOMIC FREEDOM        1.0000000     -0.1465776 0.1685476
## access_sea_bin         -0.1465776      1.0000000 0.1171111
## trade_usd               0.1685476      0.1171111 1.0000000
# Visualizar la matriz con colores
corrplot(cor_matrix, method = "color",
         col = colorRampPalette(c("red", "white", "blue"))(200),
         type = "full", addCoef.col = "black",
         number.cex = 0.8, tl.cex = 1, tl.col = "black")

Vemos que nuestra hipotesis inicial pierde fuerza debido a que la correlacion entre las variables es casi nula. Aun asi, comprobamos la correlacion por pais y realizamos una visualizacion en un mapa.

Comprobar las correlaciones por Pais

Esta correlacion, los paises tenian que tener un minimo de 3 observaciones, es decir, tres años al menos con datos. Para realiza la correlacion por pais, no utilizamos la variable de “acces_sea_bin”, debido a que al ser tan repetitiva da errores.

# Calcular la correlación entre trade_usd y libertad_economica por país (solo para países con al menos 3 observaciones)
correlaciones_por_pais <- tabla_filtrada %>%
  group_by(Pais) %>%
  filter(n() >= 3) %>%
  summarise(
    cor_trade_libertad = cor(trade_usd, `ECONOMIC FREEDOM`),  # Correlación entre trade_usd y libertad_economica
    n_obs = n(),  # Número de observaciones por país
    .groups = "drop"
  )

# Ver los resultados
print(correlaciones_por_pais)
## # A tibble: 65 × 3
##    Pais       cor_trade_libertad n_obs
##    <chr>                   <dbl> <int>
##  1 Algeria                0.315     10
##  2 Angola                 0.123      8
##  3 Argentina             -0.196     10
##  4 Australia             -0.554     10
##  5 Austria                0.134      9
##  6 Azerbaijan            -0.0467     9
##  7 Bangladesh             0.654      8
##  8 Belarus                0.415     10
##  9 Belgium                0.313     10
## 10 Brazil                 0.187     10
## # ℹ 55 more rows

Visualizar la correlacion en un mapa de calor

En esta visualizacion, corroboramos que la Hipotesis Inicial aunque tenia sentido parace que resulta erronea debido a que muchos paises se hace dificil explicar la correlacion entre sus exportaciones y su libertad economica

# 1. Calcular correlaciones por país
correlaciones_por_pais <- tabla_filtrada %>%
  group_by(Pais) %>%
  filter(n() >= 2) %>%
  summarise(
    cor_trade_libertad = cor(trade_usd, `ECONOMIC FREEDOM`, use = "complete.obs"),
    economic_freedom = mean(`ECONOMIC FREEDOM`, na.rm = TRUE),
    trade_usd = mean(trade_usd, na.rm = TRUE),
    Geographical_Particularity = first(`Geographical Particularity`),
    .groups = "drop"
  ) %>%
  rename(name = Pais)

# 2. Obtener geometría mundial
world <- ne_countries(scale = "medium", returnclass = "sf")

# 3. Unir los datos de correlación y comercio con la geometría
mapa_sf <- left_join(world, correlaciones_por_pais, by = "name")

# 4. Crear etiquetas emergentes para el mapa
mapa_sf$popup <- paste0(
  "<strong>País: </strong>", mapa_sf$name, "<br/>",
  "<strong>ISO: </strong>", mapa_sf$iso_a3, "<br/>",
  "<strong>Geografía: </strong>", mapa_sf$Geographical_Particularity, "<br/>",
  "<strong>Libertad Económica: </strong>", round(mapa_sf$economic_freedom, 2), "<br/>",
  "<strong>Trade USD (miles de millones): </strong>$", format(round(mapa_sf$trade_usd, 0), big.mark = ","), "<br/>",
  "<strong>Correlación (Trade ~ Libertad): </strong>", round(mapa_sf$cor_trade_libertad, 2)
)

# 5. Crear el mapa interactivo
leaflet(data = mapa_sf) %>%
  addProviderTiles("CartoDB.Positron") %>%
  addPolygons(
    fillColor = ~colorNumeric(palette = "RdYlBu", domain = mapa_sf$cor_trade_libertad)(cor_trade_libertad),
    fillOpacity = 0.7,
    color = "#BDBDC3",
    weight = 1,
    popup = ~popup
  ) %>%
  addLegend(
    pal = colorNumeric("RdYlBu", domain = mapa_sf$cor_trade_libertad),
    values = ~cor_trade_libertad,
    position = "bottomright",
    title = "Correlación Trade ~ Libertad"
  )

Debido a esto, realizamos una PCA para tratar de localizar cuales son las variables mas influyentes, con mayor peso, y volver a realizar la correlacion para comprobar si con estas variables se pueden obtener unas mejores conclusiones.

Realizar la PCA

# === 1. CARGAR BASE ===
df <- read_excel("libertad_economica.xlsx", col_types = "text")

# Lista de países seleccionados
paises_deseados <- c("Algeria", "Angola", "Argentina", "Australia", "Austria", "Azerbaijan", "Bangladesh",
                     "Belarus", "Belgium", "Brazil", "Bulgaria", "Canada", "Chile", "China", "Colombia",
                     "Czechia", "Denmark", "Egypt", "Finland", "France", "Germany", "Greece", "Hungary",
                     "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy", "Japan", "Kazakhstan",
                     "South Korea", "Kuwait", "Libya", "Lithuania", "Malaysia", "Mexico", "Morocco",
                     "Netherlands", "New Zealand", "Nigeria", "Norway", "Oman", "Pakistan", "Peru",
                     "Philippines", "Poland", "Portugal", "Qatar", "Romania", "Russia", "Saudi Arabia",
                     "Singapore", "South Africa", "Spain", "Sweden", "Switzerland", "Thailand", "Turkey",
                     "Ukraine", "United Kingdom", "United States of America", "Venezuela", "Vietnam")
# Filtrar por países deseados
df_filtrado <- df %>% 
  filter(Pais %in% paises_deseados)

# Convertir todas las columnas EXCEPTO 'Pais' a numérico (incluso si vienen como texto)
df_filtrado <- df_filtrado %>%
  mutate(across(-Pais, ~ as.numeric(as.character(.))))

# Guardar el índice ECONOMIC FREEDOM para compararlo con la PCA
freedom <- df_filtrado %>%
  group_by(Pais) %>%
  summarise(ECONOMIC_FREEDOM = mean(`ECONOMIC FREEDOM`, na.rm = TRUE)) %>%
  arrange(Pais)

# Crear base final para PCA
df_media <- df_filtrado %>%
  group_by(Pais) %>%
  summarise(across(where(is.numeric), mean, na.rm = TRUE)) %>%
  select(-any_of(c("year", "rank", "quartile", "ECONOMIC FREEDOM"))) %>%
  arrange(Pais)

# Preparar para PCA
df_pca <- df_media %>%
  select(-any_of(c("Pais", "ISO_code"))) %>%
  as.data.frame()
rownames(df_pca) <- df_media$Pais

# Imputar los valores faltantes con la media de cada variable:
for (col in names(df_pca)) {
  df_pca[[col]][is.na(df_pca[[col]]) | is.nan(df_pca[[col]])] <- mean(df_pca[[col]], na.rm = TRUE)
}

# Verificación final
stopifnot(is.data.frame(df_pca))
stopifnot(all(sapply(df_pca, is.numeric)))

Ejecutar la PCA

pca_res <- PCA(df_pca, scale.unit = TRUE, graph = FALSE)

*** Visualizaciones

fviz_eig(pca_res, addlabels = TRUE, ylim = c(0, 50))  # Scree plot

fviz_pca_biplot(pca_res, repel = TRUE, col.var = "contrib",
            gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"))  # Biplot

# Gráfico de variables sin etiquetas, solo flechas con color por contribución
fviz_pca_var(pca_res,
                      col.var = "contrib",
                      gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
                      ) 

library(factoextra)

# Contribución de variables al PC1
fviz_contrib(pca_res, choice = "var", axes = 1, top = 10) + 
  ggtitle("Contribución de variables al PC1")

# Contribución variables al PC2
fviz_contrib(pca_res, choice = "var", axes = 2, top = 10) + 
  ggtitle("Contribución de variables al PC2")

Justificación del uso de PCA frente a otros métodos

  1. Objetivo del análisis: simplificación e interpretación

El propósito principal de nuestro estudio es reducir la complejidad de un conjunto de variables económicas y geográficas manteniendo la mayor parte de la información posible. PCA es especialmente adecuado para este fin, ya que:

Permite identificar patrones de correlación entre variables.

Genera componentes ortogonales que facilitan la interpretación y la representación en un espacio reducido (2D o 3D).

Facilita la creación de índices sintéticos, como el “índice de libertad económica ajustado” o similares.

  1. Naturaleza de los datos: cuantitativos y correlacionados

Todas nuestras variables (trade_usd, 2_property_rights, 4_trade, etc.) son cuantitativas y continúas, y presentan niveles significativos de correlación entre ellas. PCA explota precisamente esta redundancia para crear nuevas variables no correlacionadas.

  1. Otros métodos, como ICA o t-SNE:

ICA busca independencia estadística (más fuerte que no correlación), lo cual no es nuestro objetivo.

t-SNE y UMAP son métodos no lineales orientados a la visualización y no permiten interpretar fácilmente la contribución de cada variable original a los componentes.

Calcular la correlacion entre Nuevas Variables (Pearson)

# Filtrar la tabla final y seleccionar solo las columnas específicas
tabla_filtrada <- tabla_final %>%
  select(Pais, ISO_code, year, `Geographical Particularity`, `ECONOMIC FREEDOM`,
         access_sea_bin, , trade_usd, `3_sound_money`, `5c_business_reg`, `2_property_rights`, `4_trade`)

# Convertir las columnas Overall Score y trade_usd a numéricas
tabla_filtrada <- tabla_filtrada %>%
  mutate(
    trade_usd = as.numeric(trade_usd),
    `ECONOMIC FREEDOM` = as.numeric(`ECONOMIC FREEDOM`),
    `3_sound_money` = as.numeric(`3_sound_money`),
    `5c_business_reg` = as.numeric(`5c_business_reg`),
    `2_property_rights` = as.numeric(`2_property_rights`),
    `4_trade` = as.numeric(`4_trade`),
  )

# Filtrar tabla_final a solo las columnas necesarias
tabla_cor <- tabla_filtrada %>%
  select(`2_property_rights`, `4_trade`, `3_sound_money`, `5c_business_reg`, trade_usd) 

# Calcular la matriz de correlación
cor_matrix <- cor(tabla_cor, use = "complete.obs")

# Mostrar la matriz de correlación
print(cor_matrix)
##                   2_property_rights   4_trade 3_sound_money 5c_business_reg
## 2_property_rights         1.0000000 0.6923599     0.6662952       0.7432326
## 4_trade                   0.6923599 1.0000000     0.7199910       0.6776203
## 3_sound_money             0.6662952 0.7199910     1.0000000       0.5660605
## 5c_business_reg           0.7432326 0.6776203     0.5660605       1.0000000
## trade_usd                 0.2620193 0.1031027     0.2248346       0.1566792
##                   trade_usd
## 2_property_rights 0.2620193
## 4_trade           0.1031027
## 3_sound_money     0.2248346
## 5c_business_reg   0.1566792
## trade_usd         1.0000000
# Visualizar la matriz con colores
corrplot(cor_matrix, method = "color",
         col = colorRampPalette(c("red", "white", "blue"))(200),
         type = "full", addCoef.col = "black",
         number.cex = 0.8, tl.cex = 1, tl.col = "black")

Como era de esperar gracias a la PCA las variables tienen una gran correlacion entre ellas pero siguen teniendo una correlacion baja con el valor de las exportaciones. Por eso probamos una correlacion Spearman para ver si cambia algo.

Correlacion Spearman

# Filtrar la tabla final y seleccionar solo las columnas específicas
tabla_filtrada <- tabla_final %>%
  select(Pais, ISO_code, year, `Geographical Particularity`, `ECONOMIC FREEDOM`,
         access_sea_bin, trade_usd, `3_sound_money`, `5c_business_reg`, `2_property_rights`, `4_trade`)

# Convertir las columnas a numéricas
tabla_filtrada <- tabla_filtrada %>%
  mutate(
    trade_usd = as.numeric(trade_usd),
    `ECONOMIC FREEDOM` = as.numeric(`ECONOMIC FREEDOM`),
    `3_sound_money` = as.numeric(`3_sound_money`),
    `5c_business_reg` = as.numeric(`5c_business_reg`),
    `2_property_rights` = as.numeric(`2_property_rights`),
    `4_trade` = as.numeric(`4_trade`)
  )

# Filtrar tabla a solo las columnas necesarias
tabla_cor <- tabla_filtrada %>%
  select(`2_property_rights`, `4_trade`, `3_sound_money`, `5c_business_reg`, trade_usd)

# Calcular la matriz de correlación de Spearman
cor_matrix <- cor(tabla_cor, use = "complete.obs", method = "spearman")

# Mostrar la matriz de correlación
print(cor_matrix)
##                   2_property_rights   4_trade 3_sound_money 5c_business_reg
## 2_property_rights         1.0000000 0.6964299     0.6867933       0.7570379
## 4_trade                   0.6964299 1.0000000     0.6918219       0.6386557
## 3_sound_money             0.6867933 0.6918219     1.0000000       0.5114182
## 5c_business_reg           0.7570379 0.6386557     0.5114182       1.0000000
## trade_usd                 0.3885797 0.1758924     0.3612481       0.3002451
##                   trade_usd
## 2_property_rights 0.3885797
## 4_trade           0.1758924
## 3_sound_money     0.3612481
## 5c_business_reg   0.3002451
## trade_usd         1.0000000
# Visualizar la matriz con colores
corrplot(cor_matrix, method = "color",
         col = colorRampPalette(c("red", "white", "blue"))(200),
         type = "full", addCoef.col = "black",
         number.cex = 0.8, tl.cex = 1, tl.col = "black")

Con esta correlacion, obtenemos una mayor corrleacion en trade_usd.

¿Por que nos quedamos con Spearman?

✅ ¿Qué implica esto? Pearson mide la relación lineal entre dos variables cuantitativas continuas.

Es sensible a los valores extremos (outliers) y asume una relación lineal y normalidad de los datos.

🧠 ¿Qué podrías usar alternativamente? “spearman”: si sospechas que la relación es monótona pero no lineal, o si hay valores atípicos.

Normalizacion de tabla_filtrada

Antes de realizaf el clustering, vamos a normalizar la tabla.

# 1. Calcular la media por país de variables numéricas y mantener info auxiliar
tabla_media <- tabla_filtrada %>%
  group_by(Pais) %>%
  summarise(
    ISO_code = first(ISO_code),
    Geographical_Particularity = first(`Geographical Particularity`),
    trade_usd = mean(trade_usd, na.rm = TRUE),
    `2_property_rights` = mean(`2_property_rights`, na.rm = TRUE),
    `4_trade` = mean(`4_trade`, na.rm = TRUE),
    `3_sound_money` = mean(`3_sound_money`, na.rm = TRUE),
    `5c_business_reg` = mean(`5c_business_reg`, na.rm = TRUE),
    .groups = "drop"
  )

# 2. Escalar variables numéricas (sin tocar columnas auxiliares)
variables_numericas <- tabla_media %>%
  select(trade_usd, `2_property_rights`, `4_trade`, `3_sound_money`, `5c_business_reg`)

variables_escaladas <- scale(variables_numericas)

# 3. Combinar con info auxiliar
tabla_escalada <- bind_cols(
  tabla_media %>% select(Pais, ISO_code, Geographical_Particularity),
  as_tibble(variables_escaladas)
)

Dendograma Paises

Para evitar que la correlacion se rompa por la diferencia comercial de paises que por sus condiciones tienen un valor de exportaciones alto. Vamos a realizar un dendograma y hacer la visualizacion del mapa de manera correcta sin distorsiones.

# 1. Preparar matriz numérica
datos_trade <- tabla_escalada %>%
  select(Pais, trade_usd) %>%
  drop_na()

# 2. Convertir a matriz
matriz_trade <- as.matrix(datos_trade$trade_usd)
rownames(matriz_trade) <- datos_trade$Pais

# 3. Calcular distancias (euclidianas por defecto)
distancias <- dist(matriz_trade)

# 4. Clustering jerárquico
hc <- hclust(distancias, method = "ward.D2")

# 5. Crear dendrograma
dend <- as.dendrogram(hc)

# 6. Colorear por clústeres (por ejemplo, k = 4)
k <- 6
dend_coloreado <- color_branches(dend, k = k)

# 7. Graficar
plot(dend_coloreado,
     main = paste("Dendrograma jerárquico por trade_usd (", k, "clústeres)"),
     ylab = "Distancia",
     cex = 0.7)

Hemos dividido los paises que estamos estudiando en 6 clasters segun su valor deexportaciones

Mapa Mundi Correlaciones Interactivo

Para visualizar como cada variable se relaciona con las otras en cada pais creamos un mapa interactivo donde se puede seleccionar la variable principal que realiza la correlacion.

# ---------- DATOS Y CLUSTERIZACIÓN ----------

# Variables
vars <- c("trade_usd", "2_property_rights", "4_trade", "3_sound_money", "5c_business_reg")

# Crear tabla de trade_usd por país (media)
tabla_cluster <- tabla_filtrada %>%
  group_by(Pais) %>%
  summarise(trade_usd = mean(trade_usd, na.rm = TRUE), .groups = "drop")

# Normalización
tabla_cluster$trade_usd_z <- scale(tabla_cluster$trade_usd)

# Clustering jerárquico
dist_matrix <- dist(tabla_cluster$trade_usd_z)
hc <- hclust(dist_matrix, method = "ward.D2")
tabla_cluster$cluster <- cutree(hc, k = 6)

# Agregar clúster a la tabla original
tabla_filtrada_cluster <- left_join(tabla_filtrada, tabla_cluster %>% select(Pais, cluster), by = "Pais")

tabla_filtrada_cluster <- tabla_filtrada_cluster %>%
  mutate(trade_usd = trade_usd / 1000)


# ---------- APLICACIÓN SHINY CON MAPA ----------

ui <- fluidPage(
  titlePanel("Mapa de correlaciones por clúster"),
  sidebarLayout(
    sidebarPanel(
      selectInput("cluster_id", "Selecciona el clúster:", choices = 1:6, selected = 1)
    ),
    mainPanel(
      leafletOutput("mapa", height = 650)
    )
  )
)

server <- function(input, output) {
  output$mapa <- renderLeaflet({
    cluster_sel <- input$cluster_id
    otras_vars <- setdiff(vars, "trade_usd")
    
    # Filtrar por clúster seleccionado
    datos_cluster <- tabla_filtrada_cluster %>%
      filter(cluster == cluster_sel)
    
    # Calcular correlaciones por país
    correlaciones <- datos_cluster %>%
      group_by(Pais) %>%
      filter(n() >= 3) %>%
      summarise(
        across(all_of(otras_vars), ~{
          valid <- complete.cases(.x, trade_usd)
          if (sum(valid) >= 2) cor(.x[valid], trade_usd[valid], method = "spearman") else NA_real_
        }, .names = "cor_{.col}"),
        mean_correlation = mean(c_across(starts_with("cor_")), na.rm = TRUE),
        base_mean = mean(trade_usd, na.rm = TRUE),
        .groups = "drop"
      ) %>%
      rename(name = Pais)

    # Mapa base
    world <- ne_countries(scale = "medium", returnclass = "sf")
    mapa_sf <- left_join(world, correlaciones, by = "name")

    # Etiquetas
    mapa_sf$popup <- apply(mapa_sf, 1, function(row) {
      cors <- paste0("<strong>Correlación con ", otras_vars, ": </strong>", 
                     format(round(as.numeric(row[paste0("cor_", otras_vars)]), 2)), collapse = "<br/>")
      paste0(
        "<strong>País: </strong>", row["name"], "<br/>",
        "<strong>Promedio trade_usd: </strong>$", format(round(as.numeric(row["base_mean"]), 2), big.mark = ","), "<br/>",
        cors, "<br/>",
        "<strong><u>Correlación promedio: </u></strong>", round(as.numeric(row["mean_correlation"]), 2)
      )
    })

    # Mapa interactivo
    leaflet(data = mapa_sf) %>%
      addProviderTiles("CartoDB.Positron") %>%
      addPolygons(
        fillColor = ~colorNumeric("RdYlBu", domain = mapa_sf$mean_correlation)(mean_correlation),
        fillOpacity = 0.7,
        color = "#BDBDC3",
        weight = 1,
        popup = ~popup
      ) %>%
      addLegend(
        pal = colorNumeric("RdYlBu", domain = mapa_sf$mean_correlation),
        values = ~mean_correlation,
        position = "bottomright",
        title = "Media de correlaciones"
      )
  })
}

# Ejecutar aplicación
shinyApp(ui, server)
Shiny applications not supported in static R Markdown documents

Mapa Mundi Final

Juntamos todos los clusters en uno unico

# ---------- DATOS Y CLUSTERIZACIÓN ----------

# Variables a considerar
vars <- c("trade_usd", "2_property_rights", "4_trade", "3_sound_money", "5c_business_reg")

# Tabla resumida por país
tabla_cluster <- tabla_filtrada %>%
  group_by(Pais) %>%
  summarise(trade_usd = mean(trade_usd, na.rm = TRUE), .groups = "drop")

# Normalización
tabla_cluster$trade_usd_z <- scale(tabla_cluster$trade_usd)

# Clustering jerárquico
dist_matrix <- dist(tabla_cluster$trade_usd_z)
hc <- hclust(dist_matrix, method = "ward.D2")
tabla_cluster$cluster <- cutree(hc, k = 6)

# Agregar clúster a los datos
tabla_filtrada_cluster <- left_join(tabla_filtrada, tabla_cluster %>% select(Pais, cluster), by = "Pais")
tabla_filtrada_cluster <- tabla_filtrada_cluster %>%
  mutate(trade_usd = trade_usd / 1000)

# ---------- CORRELACIONES POR PAÍS ----------

otras_vars <- setdiff(vars, "trade_usd")

correlaciones <- tabla_filtrada_cluster %>%
  group_by(Pais, cluster) %>%
  filter(n() >= 3) %>%
  summarise(
    across(all_of(otras_vars), ~{
      valid <- complete.cases(.x, trade_usd)
      if (sum(valid) >= 2) cor(.x[valid], trade_usd[valid], method = "spearman") else NA_real_
    }, .names = "cor_{.col}"),
    mean_correlation = mean(c_across(starts_with("cor_")), na.rm = TRUE),
    base_mean = mean(trade_usd, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  rename(name = Pais)

# ---------- MAPA INTERACTIVO ÚNICO ----------

# Obtener geometría mundial
world <- ne_countries(scale = "medium", returnclass = "sf")

# Unir mapa con datos
mapa_sf <- left_join(world, correlaciones, by = "name")

# Etiquetas del popup
mapa_sf$popup <- apply(mapa_sf, 1, function(row) {
  cors <- paste0("<strong>Correlación con ", otras_vars, ": </strong>", 
                 format(round(as.numeric(row[paste0("cor_", otras_vars)]), 2)), collapse = "<br/>")
  paste0(
    "<strong>País: </strong>", row["name"], "<br/>",
    "<strong>Clúster: </strong>", row["cluster"], "<br/>",
    "<strong>Promedio trade_usd: </strong>$", format(round(as.numeric(row["base_mean"]), 2), big.mark = ","), "<br/>",
    cors, "<br/>",
    "<strong><u>Correlación promedio: </u></strong>", round(as.numeric(row["mean_correlation"]), 2)
  )
})

# Colores por clúster (opcional: puedes usar colores distintos por clúster si prefieres)
paleta_color <- colorNumeric("RdYlBu", domain = mapa_sf$mean_correlation)

# Crear mapa interactivo
leaflet(data = mapa_sf) %>%
  addProviderTiles("CartoDB.Positron") %>%
  addPolygons(
    fillColor = ~paleta_color(mean_correlation),
    fillOpacity = 0.7,
    color = "#BDBDC3",
    weight = 1,
    popup = ~popup
  ) %>%
  addLegend(
    pal = paleta_color,
    values = ~mean_correlation,
    position = "bottomright",
    title = "Correlación media con trade_usd"
  )