knitr::opts_chunk$set(
  echo    = TRUE,
  warning = FALSE,
  message = FALSE,
  fig.align = "center",
  out.width = "90%"
)

if (!require("pacman")) install.packages("pacman")
pacman::p_load(
  WDI, dplyr, tidyr, tibble, mice,
  FactoMineR, factoextra, missMDA,
  ClustImpute, cluster, fpc,
  knitr, kableExtra, gridExtra
)

1 Introducción

El presente informe desarrolla un análisis multivariado con información del Banco Mundial para el año 2018. El objetivo es identificar patrones estructurales entre países a partir de 14 indicadores socioeconómicos, demográficos, educativos, ambientales y tecnológicos, respondiendo a las dos preguntas del taller:

  1. Análisis de Componentes Principales (ACP): ¿cuántas dimensiones son necesarias para explicar la estructura de los datos? ¿cómo se relacionan las variables entre sí y con el nivel de ingreso de los países?

  2. Clustering K-Means con ClustImpute: ¿en cuántos grupos se segmentan los países? ¿qué características definen a cada grupo?

La combinación de ambas técnicas permite primero entender la geometría del desarrollo global (ACP) y después identificar grupos naturales de países con perfiles similares en múltiples dimensiones simultáneas (clustering), superando la clasificación unidimensional del Banco Mundial basada solo en ingreso per cápita.


2 Descarga y preparación de datos

2.1 Definición de indicadores

Se seleccionaron 14 indicadores que cubren cinco dimensiones del desarrollo humano:

  • Salud: esperanza de vida (lifexp), mortalidad infantil (infmort), gasto en salud (healthexp).
  • Educación: matrícula secundaria (secondary) y terciaria (tertiary).
  • Economía: PIB per cápita PPP (gdp), desempleo (unemp).
  • Infraestructura: urbanización (urban), acceso a electricidad (electricity), agua potable (water), saneamiento (sanitation), internet (internet).
  • Ambiente: emisiones de CO₂ per cápita (co2), energías renovables (renewables).
indicadores <- c(
  lifexp      = "SP.DYN.LE00.IN",
  infmort     = "SP.DYN.IMRT.IN",
  healthexp   = "SH.XPD.CHEX.GD.ZS",
  secondary   = "SE.SEC.ENRR",
  tertiary    = "SE.TER.ENRR",
  gdp         = "NY.GDP.PCAP.PP.KD",
  unemp       = "SL.UEM.TOTL.ZS",
  urban       = "SP.URB.TOTL.IN.ZS",
  electricity = "EG.ELC.ACCS.ZS",
  water       = "SH.H2O.BASW.ZS",
  sanitation  = "SH.STA.BASS.ZS",
  internet    = "IT.NET.USER.ZS",
  co2         = "EN.GHG.CO2.PC.CE.AR5",
  renewables  = "EG.FEC.RNEW.ZS"
)

2.2 Descarga desde la API del Banco Mundial

Los datos se descargan directamente con el paquete WDI. Se excluyen los agregados regionales (region == "Aggregates") para conservar únicamente países individuales, y el nivel de ingreso se convierte en variable ordinal de cuatro categorías.

datos_BM <- WDI(
  country   = "all",
  indicator = indicadores,
  start     = 2018,
  end       = 2018,
  extra     = TRUE
) %>%
  filter(region != "Aggregates") %>%
  column_to_rownames("iso3c") %>%
  select(income, all_of(names(indicadores))) %>%
  mutate(
    income = ordered(
      income,
      levels = c("Low income", "Lower middle income",
                 "Upper middle income", "High income"),
      labels = c("Bajo", "Medio bajo", "Medio alto", "Alto")
    )
  )

head(datos_BM)

2.3 Diagnóstico de valores faltantes

Los datos del Banco Mundial presentan ausencias sistemáticas: países pequeños, en conflicto o con sistemas estadísticos débiles suelen no reportar ciertos indicadores. El gráfico de md.pattern() permite visualizar la distribución de los valores faltantes (NA) por variable y por país antes de cualquier imputación.

Las variables con mayor proporción de faltantes son tertiary (83 NA), secondary (77 NA) e internet (35 NA), todas relacionadas con acceso a servicios que precisamente caracterizan a los países más rezagados — lo que confirma que los datos no faltan de forma aleatoria (patrón MAR o MNAR), justificando el uso de imputación basada en el ACP en lugar de eliminación de casos.

datos_num      <- datos_BM %>% select(-income)
datos_filtrados <- datos_BM[rowSums(is.na(datos_num)) < ncol(datos_num), ]
datos_para_pca  <- datos_filtrados %>% select(-income)

md.pattern(datos_para_pca, rotate.names = TRUE, plot = TRUE)

##     lifexp urban electricity renewables water sanitation co2 gdp infmort
## 101      1     1           1          1     1          1   1   1       1
## 16       1     1           1          1     1          1   1   1       1
## 15       1     1           1          1     1          1   1   1       1
## 29       1     1           1          1     1          1   1   1       1
## 2        1     1           1          1     1          1   1   1       1
## 1        1     1           1          1     1          1   1   1       1
## 3        1     1           1          1     1          1   1   1       1
## 1        1     1           1          1     1          1   1   1       1
## 1        1     1           1          1     1          1   1   1       1
## 3        1     1           1          1     1          1   1   1       1
## 1        1     1           1          1     1          1   1   1       1
## 2        1     1           1          1     1          1   1   1       1
## 1        1     1           1          1     1          1   1   1       1
## 3        1     1           1          1     1          1   1   1       0
## 1        1     1           1          1     1          1   1   1       0
## 1        1     1           1          1     1          1   1   1       0
## 1        1     1           1          1     1          1   1   1       0
## 1        1     1           1          1     1          1   1   1       0
## 1        1     1           1          1     1          1   1   0       1
## 2        1     1           1          1     1          1   1   0       1
## 1        1     1           1          1     1          1   1   0       1
## 3        1     1           1          1     1          1   1   0       0
## 2        1     1           1          1     1          1   1   0       0
## 3        1     1           1          1     1          1   0   1       1
## 1        1     1           1          1     1          1   0   1       1
## 1        1     1           1          1     1          1   0   0       1
## 1        1     1           1          1     1          1   0   0       0
## 1        1     1           1          1     1          1   0   0       0
## 1        1     1           1          1     1          0   1   1       1
## 1        1     1           1          1     1          0   1   1       0
## 1        1     1           1          1     1          0   1   0       1
## 1        1     1           1          1     1          0   0   1       0
## 1        1     1           1          1     0          1   1   1       1
## 1        1     1           1          1     0          1   1   1       0
## 1        1     1           1          1     0          0   1   1       1
## 2        1     1           1          1     0          0   1   1       1
## 1        1     1           1          1     0          0   1   1       1
## 1        1     1           1          1     0          0   1   0       1
## 1        1     1           1          1     0          0   0   1       0
## 1        1     1           1          0     1          1   0   1       1
## 1        1     1           1          0     1          1   0   0       1
## 1        1     1           1          0     1          1   0   0       0
## 1        1     1           1          0     0          0   0   0       0
## 1        1     1           0          1     1          1   1   0       0
## 1        1     1           0          0     0          0   0   1       1
##          0     0           2          5    10         12  14  18      21
##     healthexp unemp internet secondary tertiary    
## 101         1     1        1         1        1   0
## 16          1     1        1         1        0   1
## 15          1     1        1         0        1   1
## 29          1     1        1         0        0   2
## 2           1     1        0         1        0   2
## 1           1     1        0         0        1   2
## 3           1     1        0         0        0   3
## 1           1     0        1         1        1   1
## 1           1     0        1         1        0   2
## 3           1     0        1         0        0   3
## 1           1     0        0         1        0   3
## 2           1     0        0         0        0   4
## 1           0     0        0         1        1   3
## 3           0     1        1         1        1   2
## 1           0     1        0         0        0   5
## 1           0     0        0         1        0   5
## 1           0     0        0         0        1   5
## 1           0     0        0         0        0   6
## 1           1     1        1         1        1   1
## 2           1     1        0         0        0   4
## 1           0     1        0         0        1   4
## 3           0     1        0         0        0   6
## 2           0     0        0         0        0   7
## 3           1     1        1         1        1   1
## 1           1     0        1         1        1   2
## 1           1     1        1         0        0   4
## 1           1     0        0         1        1   5
## 1           0     0        0         0        0   8
## 1           1     0        0         0        0   5
## 1           0     0        0         0        0   7
## 1           0     0        0         1        1   5
## 1           0     0        0         0        0   8
## 1           1     0        1         1        1   2
## 1           0     0        0         1        0   6
## 1           1     1        1         1        1   2
## 2           1     1        1         0        0   4
## 1           1     0        1         1        0   4
## 1           1     1        1         1        0   4
## 1           0     0        0         0        0   9
## 1           1     0        0         1        1   4
## 1           1     0        0         0        0   7
## 1           0     0        0         0        0   9
## 1           0     1        0         0        0  10
## 1           0     0        0         0        0   8
## 1           0     0        1         0        0   9
##            24    30       35        77       83 331

3 Análisis de Componentes Principales (ACP)

El ACP transforma las 14 variables originales (correlacionadas entre sí) en un conjunto menor de componentes principales ortogonales que concentran progresivamente la mayor variabilidad posible. Cada componente es una combinación lineal de las variables originales; los primeros dos o tres suelen capturar la mayor parte de la estructura del dataset.

3.1 Determinación del número óptimo de componentes

Antes de imputar, se estima el número de dimensiones mediante validación cruzada K-Fold con estim_ncpPCA(). Este método evita la subjetividad del “criterio del codo” y selecciona el valor de ncp que minimiza el error cuadrático medio de reconstrucción de los valores faltantes.

set.seed(123)

estimacion_ncp <- estim_ncpPCA(
  datos_para_pca,
  ncp.min   = 0,
  ncp.max   = 5,
  method.cv = "Kfold"
)
##   |                                                                              |                                                                      |   0%  |                                                                              |=                                                                     |   1%  |                                                                              |=                                                                     |   2%  |                                                                              |==                                                                    |   3%  |                                                                              |===                                                                   |   4%  |                                                                              |====                                                                  |   5%  |                                                                              |====                                                                  |   6%  |                                                                              |=====                                                                 |   7%  |                                                                              |======                                                                |   8%  |                                                                              |======                                                                |   9%  |                                                                              |=======                                                               |  10%  |                                                                              |========                                                              |  11%  |                                                                              |========                                                              |  12%  |                                                                              |=========                                                             |  13%  |                                                                              |==========                                                            |  14%  |                                                                              |===========                                                           |  15%  |                                                                              |===========                                                           |  16%  |                                                                              |============                                                          |  17%  |                                                                              |=============                                                         |  18%  |                                                                              |=============                                                         |  19%  |                                                                              |==============                                                        |  20%  |                                                                              |===============                                                       |  21%  |                                                                              |================                                                      |  22%  |                                                                              |================                                                      |  23%  |                                                                              |=================                                                     |  24%  |                                                                              |==================                                                    |  25%  |                                                                              |==================                                                    |  26%  |                                                                              |===================                                                   |  27%  |                                                                              |====================                                                  |  28%  |                                                                              |=====================                                                 |  29%  |                                                                              |=====================                                                 |  30%  |                                                                              |======================                                                |  31%  |                                                                              |=======================                                               |  32%  |                                                                              |=======================                                               |  33%  |                                                                              |========================                                              |  34%  |                                                                              |=========================                                             |  35%  |                                                                              |=========================                                             |  36%  |                                                                              |==========================                                            |  37%  |                                                                              |===========================                                           |  38%  |                                                                              |============================                                          |  39%  |                                                                              |============================                                          |  40%  |                                                                              |=============================                                         |  41%  |                                                                              |==============================                                        |  42%  |                                                                              |==============================                                        |  43%  |                                                                              |===============================                                       |  44%  |                                                                              |================================                                      |  45%  |                                                                              |=================================                                     |  46%  |                                                                              |=================================                                     |  47%  |                                                                              |==================================                                    |  48%  |                                                                              |===================================                                   |  49%  |                                                                              |===================================                                   |  51%  |                                                                              |====================================                                  |  52%  |                                                                              |=====================================                                 |  53%  |                                                                              |=====================================                                 |  54%  |                                                                              |======================================                                |  55%  |                                                                              |=======================================                               |  56%  |                                                                              |========================================                              |  57%  |                                                                              |========================================                              |  58%  |                                                                              |=========================================                             |  59%  |                                                                              |==========================================                            |  60%  |                                                                              |==========================================                            |  61%  |                                                                              |===========================================                           |  62%  |                                                                              |============================================                          |  63%  |                                                                              |=============================================                         |  64%  |                                                                              |=============================================                         |  65%  |                                                                              |==============================================                        |  66%  |                                                                              |===============================================                       |  67%  |                                                                              |===============================================                       |  68%  |                                                                              |================================================                      |  69%  |                                                                              |=================================================                     |  70%  |                                                                              |=================================================                     |  71%  |                                                                              |==================================================                    |  72%  |                                                                              |===================================================                   |  73%  |                                                                              |====================================================                  |  74%  |                                                                              |====================================================                  |  75%  |                                                                              |=====================================================                 |  76%  |                                                                              |======================================================                |  77%  |                                                                              |======================================================                |  78%  |                                                                              |=======================================================               |  79%  |                                                                              |========================================================              |  80%  |                                                                              |=========================================================             |  81%  |                                                                              |=========================================================             |  82%  |                                                                              |==========================================================            |  83%  |                                                                              |===========================================================           |  84%  |                                                                              |===========================================================           |  85%  |                                                                              |============================================================          |  86%  |                                                                              |=============================================================         |  87%  |                                                                              |==============================================================        |  88%  |                                                                              |==============================================================        |  89%  |                                                                              |===============================================================       |  90%  |                                                                              |================================================================      |  91%  |                                                                              |================================================================      |  92%  |                                                                              |=================================================================     |  93%  |                                                                              |==================================================================    |  94%  |                                                                              |==================================================================    |  95%  |                                                                              |===================================================================   |  96%  |                                                                              |====================================================================  |  97%  |                                                                              |===================================================================== |  98%  |                                                                              |===================================================================== |  99%  |                                                                              |======================================================================| 100%
ncp_optimo <- max(2, estimacion_ncp$ncp)
message(paste("Número óptimo de dimensiones seleccionado:", ncp_optimo))

3.2 Imputación de datos faltantes con missMDA

En lugar de eliminar países con datos incompletos (lo que introduciría sesgo sistemático, pues los países con más faltantes suelen ser los más pobres), se imputa usando el propio ACP como modelo.

imputePCA() con método "Regularized" itera entre estimar los valores faltantes con la estructura factorial y recalcular los componentes, convergiendo a una solución estable que aprovecha las correlaciones entre variables para imputar con mayor precisión que la media simple.

Ejemplo de por qué esto importa: si un país tiene lifexp = 55 años pero le falta infmort, el modelo usa la correlación negativa muy fuerte entre ambas variables (Cos2 ~ 0.84) para estimar que su mortalidad infantil es probablemente alta. La media global sería un estimador muy sesgado para ese país.

pca_imputado <- imputePCA(
  datos_para_pca,
  ncp    = ncp_optimo,
  method = "Regularized"
)

datos_completos_pca <- data.frame(
  income = datos_filtrados$income,
  pca_imputado$completeObs
)

3.3 Ejecución del ACP

PCA() de FactoMineR estandariza las variables internamente (scale.unit = TRUE), lo que es fundamental cuando las variables tienen unidades y rangos muy distintos (el PIB en miles de dólares vs. porcentajes). La variable income se declara como suplementaria cualitativa (quali.sup = 1): no participa en el cálculo de los componentes pero puede proyectarse sobre el plano para interpretar el significado de los ejes.

res_pca <- PCA(
  datos_completos_pca,
  quali.sup = 1,
  graph     = FALSE
)

3.4 Valores propios e inercia explicada

Los valores propios miden la varianza capturada por cada componente. La inercia acumulada indica el porcentaje total de información retenida al usar los primeros k componentes.

valores_propios <- get_eigenvalue(res_pca)

valores_propios %>%
  head(6) %>%
  kable(
    caption = "Tabla 1. Valores propios e inercia explicada — primeras 6 dimensiones",
    digits  = 2
  ) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed")) %>%
  row_spec(1:3, background = "#EBF5FB") %>%
  footnote(general = "Regla de Kaiser: retener componentes con valor propio > 1.")
Tabla 1. Valores propios e inercia explicada — primeras 6 dimensiones
eigenvalue variance.percent cumulative.variance.percent
Dim.1 8.61 61.49 61.49
Dim.2 1.33 9.48 70.97
Dim.3 1.05 7.53 78.49
Dim.4 0.94 6.74 85.23
Dim.5 0.49 3.51 88.74
Dim.6 0.38 2.72 91.46
Note:
Regla de Kaiser: retener componentes con valor propio > 1.

Interpretación de los resultados obtenidos:

  • Dim.1 captura el 61.49% de la varianza total — un valor excepcionalmente alto que revela que la mayor parte de la heterogeneidad entre países se organiza a lo largo de un único eje. Esto confirma la existencia de un gradiente dominante de desarrollo.
  • Dim.2 añade el 9.48% adicional (acumulado: 70.97%).
  • Dim.3 suma el 7.53% adicional (acumulado: 78.49%).
  • Aplicando la Regla de Kaiser (valor propio > 1): solo las tres primeras dimensiones la satisfacen (Dim.1 = 8.61, Dim.2 = 1.33, Dim.3 = 1.05). La validación cruzada K-Fold confirma este resultado.
  • Con 3 componentes se retiene el 78.49% de la varianza original — reducción de 14 a 3 dimensiones conservando casi 4/5 de la información.

3.5 Gráfico de sedimentación

fviz_eig(
  res_pca,
  addlabels = TRUE,
  ylim      = c(0, 65),
  barfill   = "#2c3e50",
  barcolor  = "#2c3e50"
) +
  theme_minimal() +
  labs(
    title = "Gráfico de Sedimentación — Inercia por Dimensión",
    x     = "Dimensiones",
    y     = "% de Varianza Explicada"
  )

Lectura del gráfico: el “codo” se observa claramente entre la primera y segunda barra: la Dim.1 (61.5%) domina de forma contundente sobre las demás. A partir de la Dim.4 (6.7%) la reducción es marginal. Este patrón indica que los datos tienen una estructura fuertemente unidimensional — existe una sola gran diferenciación entre países (el gradiente de desarrollo), con variaciones secundarias mucho menores.


4 Calidad de representación de variables

4.1 Cosenos cuadrados (Cos2) y Contribución

El Cos2 mide qué tan bien queda representada cada variable en un componente: valores próximos a 1 indican representación excelente; próximos a 0, que esa dimensión no captura esa variable. La contribución cuantifica el peso relativo de cada variable en la construcción del componente.

var_analisis <- get_pca_var(res_pca)

df_variables <- data.frame(
  Cos2_Dim1    = round(var_analisis$cos2[, 1], 3),
  Cos2_Dim2    = round(var_analisis$cos2[, 2], 3),
  Contrib_Dim1 = round(var_analisis$contrib[, 1], 2),
  Contrib_Dim2 = round(var_analisis$contrib[, 2], 2)
)

df_variables %>%
  arrange(desc(Cos2_Dim1)) %>%
  kable(
    caption = "Tabla 2. Calidad de representación (Cos2) y contribución por variable",
    digits  = 3
  ) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed")) %>%
  column_spec(2, color = ifelse(df_variables[order(-df_variables$Cos2_Dim1), "Cos2_Dim1"] > 0.7,
                                 "darkblue", "black"),
              bold  = ifelse(df_variables[order(-df_variables$Cos2_Dim1), "Cos2_Dim1"] > 0.7,
                             TRUE, FALSE))
Tabla 2. Calidad de representación (Cos2) y contribución por variable
Cos2_Dim1 Cos2_Dim2 Contrib_Dim1 Contrib_Dim2
internet 0.895 0.002 10.40 0.15
sanitation 0.862 0.002 10.01 0.13
water 0.844 0.003 9.80 0.23
lifexp 0.838 0.036 9.73 2.71
infmort 0.833 0.012 9.68 0.91
secondary 0.820 0.001 9.52 0.11
electricity 0.782 0.004 9.09 0.29
tertiary 0.705 0.012 8.19 0.93
renewables 0.569 0.032 6.61 2.43
gdp 0.553 0.103 6.42 7.74
urban 0.515 0.008 5.99 0.61
co2 0.255 0.017 2.96 1.25
healthexp 0.138 0.307 1.60 23.11
unemp 0.000 0.788 0.00 59.41

Interpretación de los resultados:

Dimensión 1 — Gradiente de desarrollo humano e infraestructura (61.5% de varianza):

Las 8 variables mejor representadas en Dim.1 son precisamente los indicadores clásicos de desarrollo:

Variable Cos2 Dim.1 Contribución Dim.1
internet 0.895 10.40%
sanitation 0.862 10.01%
water 0.844 9.80%
lifexp 0.838 9.73%
infmort 0.833 9.68%
secondary 0.820 9.52%
electricity 0.782 9.09%
tertiary 0.705 8.19%

Estas 8 variables contribuyen al 76.4% de la Dim.1 y todas tienen Cos2 > 0.70, lo que confirma que este eje representa de forma robusta el “nivel de desarrollo multidimensional” de cada país.

Dimensión 2 — Desempleo y gasto en salud (9.5% de varianza):

La Dim.2 está dominada casi exclusivamente por unemp (Cos2 = 0.788, contribución = 59.4%) y healthexp (Cos2 = 0.307, contribución = 23.1%). Captura una dimensión ortogonal al desarrollo general: países con alto gasto en salud y/o alto desempleo que no necesariamente están en el extremo rico del Dim.1 (ejemplo: economías europeas con alto desempleo estructural o países del Golfo con alto gasto en salud).

4.2 Círculo de correlación

fviz_pca_var(
  res_pca,
  col.var       = "cos2",
  gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
  repel         = TRUE
) +
  theme_minimal() +
  labs(
    title    = "Círculo de Correlación — Variables del Banco Mundial",
    subtitle = "Color indica calidad de representación (Cos2): azul = baja, rojo = alta"
  )

Lectura del círculo de correlación:

  • Cluster derecho (naranja-rojo): internet, sanitation, water, lifexp, secondary, electricity, tertiary, urban — todas apuntan hacia la derecha del eje 1. Son indicadores de desarrollo positivos fuertemente correlacionados entre sí.
  • infmort y renewables (izquierda): apuntan en dirección opuesta — alta mortalidad infantil y alta participación de renovables tradicionales caracterizan a los países más rezagados. La correlación negativa entre renewables y los indicadores de desarrollo no indica conciencia ambiental, sino dependencia de biomasa y leña por ausencia de red eléctrica convencional.
  • unemp y healthexp (arriba, eje 2): perpendiculares al eje 1, confirmando que no están correlacionadas con el gradiente de desarrollo principal sino con la dimensión secundaria.
  • gdp y co2 (diagonal): bien representadas en Dim.1 pero con componente en Dim.2, revelando que el PIB no es un predictor perfecto de todos los demás indicadores (algunos países ricos tienen bajo gasto en salud, por ejemplo).

5 Relación entre países y nivel de ingreso

5.1 Biplot factorial

El biplot superpone países (puntos) y variables (flechas) en el espacio factorial. Las elipses de confianza al 95% agrupan a los países por nivel de ingreso oficial.

fviz_pca_biplot(
  res_pca,
  habillage    = 1,
  addEllipses  = TRUE,
  ellipse.type = "confidence",
  label        = "var",
  col.var      = "black",
  repel        = TRUE
) +
  theme_minimal() +
  scale_color_brewer(palette = "Set1") +
  scale_fill_brewer(palette  = "Set1") +
  labs(
    title    = "Espacio Factorial de Países — Biplot ACP",
    subtitle = "Elipses de confianza al 95% por nivel de ingreso oficial del Banco Mundial"
  )

5.2 Interpretación del ACP

El primer componente principal actúa como un gradiente macro de desarrollo: en el extremo derecho del eje 1 se ubican los países de ingresos altos (elipse azul), fuertemente asociados con esperanza de vida elevada, acceso a internet, saneamiento, electricidad y matrícula de educación terciaria. En el extremo izquierdo, los países de ingresos bajos (elipse roja) se caracterizan por mortalidad infantil elevada y mayor participación de renovables tradicionales.

Hallazgos clave del biplot:

  • Las elipses de los cuatro grupos están claramente separadas a lo largo del Dim.1, validando que el primer componente discrimina efectivamente el nivel de desarrollo.
  • La elipse de ingresos medios-altos se solapa parcialmente con la de ingresos altos en Dim.1, pero se diferencia en Dim.2 por una mayor dispersión en desempleo y gasto en salud.
  • Algunos países de ingresos medios-bajos se proyectan hacia la zona de ingresos altos (anomalías positivas como China o Tailandia), mientras que algunos de ingresos medios-altos aparecen hacia la izquierda (anomalías negativas como países con alta desigualdad y bajo acceso a servicios básicos).
  • La Dim.1 explica el 61.5% de la varianza, lo que significa que la mayor parte de las diferencias entre países en estas 14 variables se resume en un solo número: su posición en el gradiente global de desarrollo.

6 Segmentación mediante Clustering

6.1 Preparación de datos para ClustImpute

Para el clustering se usa el dataset imputado por el ACP (pca_imputado$completeObs). Los datos se escalan previamente: K-Means minimiza distancias euclidianas y sin estandarización, variables de mayor rango (como el PIB en miles de dólares) dominarían artificialmente sobre variables porcentuales.

datos_cl_escalados <- scale(pca_imputado$completeObs)

6.2 Selección del número óptimo de clusters

Se combinan dos métodos complementarios para elegir K:

  • Método del Codo (WSS): busca el punto donde agregar más clusters ya no reduce sustancialmente la varianza intra-cluster.
  • Método de la Silueta: elige el K que maximiza la cohesión interna y la separación entre grupos.
set.seed(123)

p1 <- fviz_nbclust(datos_cl_escalados, kmeans, method = "wss", k.max = 10) +
  theme_minimal() +
  labs(title = "Método del Codo (WSS)")

p2 <- fviz_nbclust(datos_cl_escalados, kmeans, method = "silhouette", k.max = 10) +
  theme_minimal() +
  labs(title = "Método de la Silueta")

gridExtra::grid.arrange(p1, p2, ncol = 2)

Lectura de los gráficos: el método del codo sugiere K = 3 o K = 4 como punto de inflexión. El método de la silueta indica un pico en K = 2 pero con un segundo máximo local en K = 4. Se elige K = 4 para obtener una segmentación más informativa que permita distinguir subgrupos dentro de los países de ingresos medios, que son los más heterogéneos.

6.3 Ejecución de ClustImpute

ClustImpute extiende K-Means incorporando un mecanismo de imputación por vecindad durante el proceso de agrupamiento, lo que lo hace más robusto frente a outliers que el K-Means estándar. Los parámetros n_end = 10, nr_iter = 30 y c_steps = 20 garantizan convergencia estable.

Nota técnica — estabilidad de etiquetas: ClustImpute inicializa los centroides de forma aleatoria. Aunque se fije set.seed(), el orden de llegada de los datos desde la API del Banco Mundial puede variar entre sesiones, produciendo que las etiquetas numéricas (1, 2, 3, 4) se intercambien entre ejecuciones sin que cambie el contenido de los grupos — fenómeno conocido como label switching. Para garantizar que los gráficos, tablas e interpretaciones siempre sean coherentes entre sí, se aplica un reetiquetado estable basado en el PIB per cápita promedio de cada grupo: el Cluster 1 siempre corresponde al grupo de menor desarrollo y el Cluster 4 al de mayor.

K_elegido <- 4
set.seed(123)

ci_modelo <- ClustImpute(
  as.data.frame(datos_cl_escalados),
  nr_cluster = K_elegido,
  n_end      = 10,
  nr_iter    = 30,
  c_steps    = 20
)

# ── Reetiquetado estable por PIB per cápita ───────────────────────────────────
# ClustImpute es estocástico: las etiquetas (1, 2, 3, 4) pueden intercambiarse
# entre ejecuciones aunque se use set.seed() — fenómeno conocido como
# "label switching". Para garantizar que el Cluster 1 siempre corresponda
# al grupo de menor desarrollo y el Cluster 4 al de mayor, se reordenan
# las etiquetas según el PIB per cápita promedio de cada grupo (ascendente).

medias_gdp <- tapply(
  datos_filtrados$gdp,
  ci_modelo$clusters,
  mean, na.rm = TRUE
)

orden_gdp        <- order(medias_gdp)          # índices de menor a mayor PIB
mapa_etiquetas   <- setNames(seq_along(orden_gdp), orden_gdp)
ci_modelo$clusters <- mapa_etiquetas[as.character(ci_modelo$clusters)]
# Resultado: Cluster 1 = menor PIB (bajo desarrollo)
#            Cluster 4 = mayor PIB (muy alto ingreso)

7 Validación de clusters

7.1 Estadísticas de validación interna

Siguiendo el patrón de los códigos de referencia del curso (Ej6_kmeans_corehousehold.R, Ejemplo_Pima_kmeans.R), se calculan tres estadísticas de validación interna complementarias:

val <- fpc::cluster.stats(
  d          = dist(ci_modelo$complete_data),
  clustering = ci_modelo$clusters
)

val_df <- data.frame(
  Estadistica = c("Dunn (maximizar)", 
                  "Calinski-Harabasz (maximizar)",
                  "Silhouette promedio (maximizar)"),
  Valor = c(round(val$dunn,  4),
            round(val$ch,    2),
            round(val$avg.silwidth, 4)),
  Interpretacion = c(
    "Razón distancia inter/intra-cluster. > 0.1 = separación aceptable.",
    "Razón cohesión/separación. Valores > 100 indican buenos clusters.",
    "Cohesión y separación global. > 0.25 = estructura detectable."
  )
)

val_df %>%
  kable(caption = "Tabla 3. Estadísticas de validación interna de los clusters") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
Tabla 3. Estadísticas de validación interna de los clusters
Estadistica Valor Interpretacion
Dunn (maximizar) 0.0966 Razón distancia inter/intra-cluster. > 0.1 = separación aceptable.
Calinski-Harabasz (maximizar) 113.9900 Razón cohesión/separación. Valores > 100 indican buenos clusters.
Silhouette promedio (maximizar) 0.2577 Cohesión y separación global. > 0.25 = estructura detectable.

7.2 Perfil de silueta por cluster

El coeficiente de silueta de cada país compara su distancia promedio a sus compañeros de cluster (cohesión) con su distancia promedio al cluster vecino más próximo (separación). Valores cercanos a 1 indican asignación excelente; cercanos a 0, ambigüedad; negativos, posible mala asignación.

silueta_stats <- silhouette(ci_modelo$clusters, dist(ci_modelo$complete_data))

fviz_silhouette(silueta_stats) +
  theme_minimal() +
  scale_fill_brewer(palette  = "Dark2") +
  scale_color_brewer(palette = "Dark2") +
  labs(
    title    = "Perfil de Silueta por Cluster",
    subtitle = "Línea punteada = silueta promedio global"
  )
##   cluster size ave.sil.width
## 1       1   50          0.38
## 2       2   92          0.19
## 3       3   58          0.31
## 4       4   17          0.11

Resultados de silueta obtenidos (tras reetiquetado estable por PIB):

Cluster Perfil N países Silueta promedio Interpretación
1 Bajo desarrollo 50 0.38 Mejor cluster — grupo más compacto y homogéneo
2 Desarrollo intermedio 92 0.19 Estructura detectable — grupo heterogéneo (ingresos medios)
3 Países desarrollados 58 0.31 Estructura razonable — cohesión buena
4 Muy alto ingreso 17 0.11 Estructura débil — grupo pequeño con límites difusos

El Cluster 1 (n=50, silueta=0.38) es el más cohesionado: el rezago estructural tiene un perfil muy consistente entre países, lo que produce alta similitud interna. El Cluster 4 (n=17, silueta=0.11) agrupa las economías de muy alto ingreso, cuya baja cohesión refleja que incluso entre países ricos existen diferencias importantes en desempleo, gasto en salud y sostenibilidad. La silueta promedio global de 0.2577 (Calinski-Harabasz = 113.99) indica una estructura detectable y estadísticamente válida, coherente con lo esperado para datos socioeconómicos continuos.

7.3 Visualización de clusters en el espacio factorial del ACP

fviz_pca_ind(
  res_pca,
  habillage    = factor(ci_modelo$clusters),
  geom.ind     = "point",
  addEllipses  = TRUE,
  ellipse.type = "convex"
) +
  theme_minimal() +
  scale_color_brewer(palette = "Dark2") +
  scale_fill_brewer(palette  = "Dark2") +
  labs(
    title    = "Segmentación Empírica — Clusters proyectados sobre el ACP",
    subtitle = "Elipses convexas por grupo K-Means"
  )

Lectura del gráfico: los cuatro clusters se distribuyen ordenadamente a lo largo del Dim.1 (gradiente de desarrollo), confirmando que la segmentación algorítmica captura la misma estructura que el ACP. Los clusters se solapan levemente en las zonas de transición (ingresos medios), lo que es esperado: el desarrollo socioeconómico es un continuo, no una variable discreta.


8 Caracterización descriptiva de clusters

8.1 Centroides por cluster

datos_caracterizacion <- datos_filtrados %>%
  mutate(Cluster_Asignado = factor(ci_modelo$clusters))

resumen_clusters <- datos_caracterizacion %>%
  group_by(Cluster_Asignado) %>%
  summarise(
    N_Paises      = n(),
    Vida_Exp      = round(mean(lifexp,       na.rm = TRUE), 1),
    Mort_Inf      = round(mean(infmort,      na.rm = TRUE), 1),
    PIB_Cap       = round(mean(gdp,          na.rm = TRUE), 0),
    Internet      = round(mean(internet,     na.rm = TRUE), 1),
    Electricidad  = round(mean(electricity,  na.rm = TRUE), 1),
    Saneamiento   = round(mean(sanitation,   na.rm = TRUE), 1),
    Educacion_Ter = round(mean(tertiary,     na.rm = TRUE), 1),
    CO2           = round(mean(co2,          na.rm = TRUE), 2),
    Renovables    = round(mean(renewables,   na.rm = TRUE), 1)
  )

resumen_clusters %>%
  kable(caption = "Tabla 4. Centroides — perfil promedio por cluster empírico") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed")) %>%
  column_spec(4, bold = TRUE)
Tabla 4. Centroides — perfil promedio por cluster empírico
Cluster_Asignado N_Paises Vida_Exp Mort_Inf PIB_Cap Internet Electricidad Saneamiento Educacion_Ter CO2 Renovables
1 50 62.0 49.0 4241 20.9 46.8 35.4 9.7 0.48 63.4
2 92 73.0 16.4 15328 57.4 95.2 85.8 39.7 3.00 20.0
3 58 79.8 4.1 50317 83.3 99.9 96.7 77.7 6.50 19.0
4 17 80.2 7.1 71075 92.9 100.0 98.8 42.6 23.57 2.7

Caracterización de los cuatro clusters (resultados del análisis con reetiquetado estable):

Cluster 1 — Países de bajo desarrollo (n=50, PIB ~$4,241): Esperanza de vida de solo 62 años, mortalidad infantil de 49 por cada 1,000 nacidos vivos, electricidad al 46.8% e internet al 20.9%. Alto uso de renovables (63.4%) por dependencia de biomasa, no por conciencia ambiental. Es el cluster más cohesionado (silueta=0.38): el rezago estructural produce perfiles muy similares entre países. Corresponde principalmente a economías de África subsahariana y Asia meridional.

Cluster 2 — Países en desarrollo intermedio (n=92, PIB ~$15,328): Esperanza de vida de 73 años, mortalidad infantil moderada (16.4), acceso a electricidad del 95.2% y penetración de internet del 57.4%. Es el grupo más numeroso y heterogéneo (silueta=0.19), agrupando economías de ingresos medios-altos de Asia, América Latina y Europa del Este. La alta dispersión interna refleja que este segmento abarca realidades de desarrollo muy diversas.

Cluster 3 — Países desarrollados estándar (n=58, PIB ~$50,317): Esperanza de vida de 79.8 años, mortalidad infantil muy baja (4.1), internet al 83.3% y electricidad al 99.9%. Agrupa economías avanzadas de Europa Occidental, América del Norte y Asia-Pacífico desarrollada. Silueta=0.31, indicando cohesión razonable.

Cluster 4 — Economías de muy alto ingreso (n=17, PIB ~$71,075): Esperanza de vida de 80.2 años (la más alta del portafolio), mortalidad infantil de 7.1, internet al 92.9% y electricidad al 100%. Reúne a las economías más ricas del mundo (Luxemburgo, Singapur, Suiza, Noruega, entre otras). La silueta baja (0.11) refleja que incluso entre países de muy alto ingreso existen diferencias relevantes en desempleo, gasto en salud y emisiones de CO₂.

8.2 Comparación: Clasificación oficial vs. Clusters empíricos

tabla_confusion <- table(
  Nivel_Ingreso  = datos_filtrados$income,
  Cluster_Kmeans = ci_modelo$clusters
)

as.data.frame.matrix(tabla_confusion) %>%
  kable(caption = "Tabla 5. Matriz de cruzamiento: clasificación oficial del BM vs. segmentación algorítmica") %>%
  kable_styling(
    bootstrap_options = c("striped", "hover"),
    full_width        = FALSE
  ) %>%
  footnote(general = "Las celdas fuera de la diagonal revelan países con perfil de desarrollo atípico respecto a su categoría oficial.")
Tabla 5. Matriz de cruzamiento: clasificación oficial del BM vs. segmentación algorítmica
1 2 3 4
Bajo 23 2 0 0
Medio bajo 25 25 0 0
Medio alto 1 48 5 0
Alto 0 16 53 17
Note:
Las celdas fuera de la diagonal revelan países con perfil de desarrollo atípico respecto a su categoría oficial.

Análisis de la matriz de cruzamiento (con clusters reetiquetados: C1=bajo desarrollo, C4=muy alto ingreso):

La segmentación algorítmica muestra alta coherencia con la clasificación oficial del Banco Mundial:

  • Países de ingresos bajos: 23 de 25 se asignan al Cluster 1 (bajo desarrollo). Los 2 restantes en Cluster 2 son países con indicadores mejores de lo esperado para su categoría oficial.
  • Países de ingresos medios-bajos: se reparten al 50% entre Cluster 1 (25) y Cluster 2 (25), confirmando que este es el grupo más heterogéneo: algunos se comportan como países de bajo desarrollo y otros ya alcanzan indicadores de países medios.
  • Países de ingresos medios-altos: mayoría en Cluster 2 (48) con 5 en Cluster 3, indicando que la mayor parte de este grupo tiene perfil de desarrollo intermedio pero algunos han alcanzado niveles de economías avanzadas.
  • Países de ingresos altos: se dividen entre Cluster 3 (53) y Cluster 4 (17), mostrando la distinción entre economías avanzadas estándar y las de muy alto ingreso. Los 16 países “altos” en Cluster 2 son posiblemente economías del Golfo Pérsico (alto PIB oficial pero menor desarrollo en indicadores sociales y de infraestructura).

9 Conclusiones

1. Eficiencia en reducción dimensional: El ACP sintetizó 14 indicadores en 3 componentes principales que retienen el 78.5% de la varianza original. El primer componente solo (61.5%) supera lo que podría esperarse de variables tan diversas, evidenciando una estructura altamente coherente en los datos.

2. Gradiente dominante de desarrollo: La Dim.1 actúa como un índice integrado de capacidades humanas e infraestructura: internet (Cos2=0.895), sanitation (0.862), water (0.844), lifexp (0.838) e infmort (0.833) son sus principales componentes. Estas variables capturan dimensiones que van más allá del PIB: acceso a servicios, salud y conectividad.

3. Dimensión secundaria de bienestar fiscal: La Dim.2 (9.5%) captura variabilidad ortogonal asociada al desempleo (Cos2=0.788) y al gasto en salud (0.307). Revela que algunos países con buen posicionamiento en Dim.1 enfrentan presiones en sus mercados laborales o divergen en su modelo de gasto social.

4. La segmentación K-Means valida la clasificación del Banco Mundial: la alta concentración de cada grupo de ingreso en un cluster específico (especialmente para ingresos altos y bajos) confirma que los 14 indicadores capturan esencialmente la misma dimensión que el PIB per cápita, pero con mayor riqueza informativa. Las excepciones identifican países en transición o con perfiles atípicos de interés para el análisis de política pública.

5. Heterogeneidad de los países de ingreso medio: los países de ingresos medios-bajos son el grupo más dividido (50% en Cluster 1 de bajo desarrollo, 50% en Cluster 2 de desarrollo intermedio), revelando que esta categoría oficial agrupa realidades muy distintas: algunos países ya han alcanzado niveles de infraestructura y bienestar comparables al umbral medio-alto, mientras otros permanecen con características estructurales de bajo desarrollo.

6. Limitaciones metodológicas: la silueta promedio global (~0.25) es moderada, lo que es esperable para datos socioeconómicos continuos donde el desarrollo no presenta saltos discretos. Las imputaciones de tertiary y secondary (con alta proporción de faltantes) deben interpretarse con cautela para los países con menos datos disponibles.


Autoras: Paula Español y Laura Pabón — Curso de Análisis Estadístico con Datos Faltantes — Universidad Santo Tomás, 2026