#_https://rstudio-pubs-static.s3.amazonaws.com/1186600_3bd61f62725d425488649f1045ab3626.html_
library(imf.data) # Extracción de datos desde la API del FMI
library(dplyr) # Manipulación de datos
##
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(tidyr) # Transformación de formatos (pivot_wider)
library(cluster) # Algoritmo PAM (K-Medianas)
library(factoextra) # Visualización de clústeres y siluetas
## Cargando paquete requerido: ggplot2
## Welcome to factoextra!
## Want to learn more? See two factoextra-related books at https://www.datanovia.com/library/principal-component-methods
library(knitr)
library(kableExtra)
##
## Adjuntando el paquete: 'kableExtra'
## The following object is masked from 'package:dplyr':
##
## group_rows
paises <- c("SLV", "GTM", "HND", "NIC", "CRI", "PAN")
datos_weo <- get_data(
"WEO",
agency_id = "IMF.RES",
filters = list(
COUNTRY = paises,
INDICATOR = c("NGDP_RPCH", "PCPIPCH"),
FREQUENCY = "A"
)
)
datos_macro <- datos_weo %>%
mutate(
TIME_PERIOD = as.numeric(TIME_PERIOD),
OBS_VALUE = as.numeric(OBS_VALUE)
) %>%
filter(TIME_PERIOD == 2023) %>%
select(COUNTRY, INDICATOR, OBS_VALUE) %>%
pivot_wider(names_from = INDICATOR, values_from = OBS_VALUE)
datos_macro %>%
kable(caption = "Proyección de indicadores en la región Centroamericana para el año 2023") %>%
kable_classic(html_font = "Times New Roman", font_size = 13) %>%
kable_styling(full_width = FALSE)
| COUNTRY | NGDP_RPCH | PCPIPCH |
|---|---|---|
| CRI | 4.791877 | 0.525186 |
| GTM | 3.533157 | 6.209335 |
| HND | 3.575892 | 6.663167 |
| NIC | 4.427794 | 8.445432 |
| PAN | 7.166329 | 1.486421 |
| SLV | 3.539157 | 4.046867 |
datos <- datos_macro %>%
mutate(across(where(is.numeric), ~ ifelse(is.na(.), mean(., na.rm = TRUE), .)))
matriz_datos <- as.data.frame(datos[, -1])
rownames(matriz_datos) <- datos$COUNTRY
datos_escalados <- scale(matriz_datos)
n_paises <- nrow(datos_escalados)
print(paste("Cantidad de países en el análisis:", n_paises))
## [1] "Cantidad de países en el análisis: 6"
as.data.frame(datos_escalados) %>%
kable(caption = "Matriz de Datos Estandarizados (Z-Scores)") %>%
kable_classic(html_font = "Times New Roman", font_size = 12) %>%
kable_styling(full_width = FALSE)
| NGDP_RPCH | PCPIPCH | |
|---|---|---|
| CRI | 0.2032584 | -1.3000014 |
| GTM | -0.6907558 | 0.5301689 |
| HND | -0.6604030 | 0.6762928 |
| NIC | -0.0553340 | 1.2501427 |
| PAN | 1.8897286 | -0.9905050 |
| SLV | -0.6864943 | -0.1660980 |
max_k <- min(10, n_paises - 1)
grafico_k_optimo <- fviz_nbclust(
x = datos_escalados,
FUNcluster = pam,
method = "silhouette",
k.max = max_k
) +
labs(
title = "Número Óptimo de Clústeres - Algoritmo PAM (K-Medianas)",
subtitle = "Criterio de Silueta Media con datos de la API del FMI",
x = "Número de clústeres (k)",
y = "Ancho promedio de silueta"
) +
theme_minimal()
print(grafico_k_optimo)
# 4. EJECUCIÓN DEL ALGORITMO PAM (K-MEDIANAS)
# Asumiendo k = 2 según el resultado óptimo de la silueta
k_opt <- 2
resultado_pam <- pam(x = datos_escalados, k = k_opt, metric = "euclidean")
medoides_reales <- rownames(datos_escalados)[resultado_pam$id.med]
cat("Los países seleccionados como medoides son:", paste(medoides_reales, collapse = ", "), "\n")
## Los países seleccionados como medoides son: PAN, GTM
library(factoextra)
fviz_cluster(
object = resultado_pam,
data = datos_escalados,
ellipse.type = "convex",
star.plot = TRUE,
repel = TRUE,
show.clust.cent = TRUE,
palette = "jco",
ggtheme = theme_minimal()
) +
labs(
title = "Grupos Macroeconómicos y sus Países Medoides",
subtitle = "Las líneas conectan cada país con su medoide asignado (GTM, PAN)",
caption = "Fuente: Elaboración propia con datos del FMI"
)
# 5. REPRESENTACIÓN GRÁFICA CORRESPONDIENTE AL ALGORITMO
# A) Gráfico de Elipsoides de Concentración y Medoides
grafico_clusters <- fviz_cluster(
object = resultado_pam,
data = datos_escalados,
ellipse.type = "convex",
repel = TRUE,
show.clust.cent = TRUE,
star.plot = TRUE
) +
labs(
title = "Agrupación mediante K-Medianas (PAM)",
subtitle = "Clustering Particional Robusto basado en Medoides Reales (API FMI)",
caption = "Fuente: Elaboración propia con datos de la API del FMI"
) +
theme_minimal()
print(grafico_clusters)
# B) Gráfico de Silueta de la Partición
grafico_silueta <- fviz_silhouette(resultado_pam) +
labs(
title = "Gráfico de Silueta para Clustering PAM (k = 2)",
subtitle = "Evaluación del ajuste individual y promedio de los clústeres"
) +
theme_minimal()
## cluster size ave.sil.width
## 1 1 2 0.29
## 2 2 4 0.66
print(grafico_silueta)