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 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")
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")]
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()
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)
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"))
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
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.
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
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.
# === 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)))
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")
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.
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.
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.
# 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.
# 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.
✅ ¿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.
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)
)
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
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)
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"
)