# Paso 1. Paquetes
pkgs <- c("readxl","dplyr","stringr","ggplot2","factoextra")
# Verifica cuáles faltan
to_install <- pkgs[!(pkgs %in% rownames(installed.packages()))]
# Instala los que falten
if(length(to_install) > 0) install.packages(to_install)
# Carga los paquetes
library(readxl)
library(dplyr)
##
## 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(stringr)
library(ggplot2)
library(factoextra)
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
# 2A: detectar fila de encabezados
raw0 <- read_excel("D:\\Anton V2\\Downloads\\vmrc.xlsx", col_names = FALSE)
## New names:
## • `` -> `...1`
## • `` -> `...2`
## • `` -> `...3`
## • `` -> `...4`
## • `` -> `...5`
## • `` -> `...6`
## • `` -> `...7`
## • `` -> `...8`
## • `` -> `...9`
## • `` -> `...10`
## • `` -> `...11`
## • `` -> `...12`
## • `` -> `...13`
## • `` -> `...14`
## • `` -> `...15`
## • `` -> `...16`
## • `` -> `...17`
## • `` -> `...18`
## • `` -> `...19`
## • `` -> `...20`
## • `` -> `...21`
## • `` -> `...22`
header_row <- which(apply(raw0, 1, function(r) any(grepl("ENTIDAD\\s*FEDERATIVA", r, TRUE))))[1]
# 2B: recargar con encabezado correcto
raw <- read_excel("D:\\Anton V2\\Downloads\\vmrc.xlsx", skip = header_row - 1)
## New names:
## • `` -> `...3`
## • `` -> `...5`
## • `` -> `...6`
## • `` -> `...7`
## • `` -> `...8`
## • `` -> `...10`
## • `` -> `...11`
## • `` -> `...12`
## • `` -> `...13`
## • `` -> `...15`
## • `` -> `...16`
## • `` -> `...17`
## • `` -> `...18`
## • `` -> `...20`
## • `` -> `...21`
## • `` -> `...22`
# normalizar nombres
nms <- names(raw)
nms <- iconv(nms, from = "", to = "ASCII//TRANSLIT")
nms <- str_replace_all(nms, "\\s+", "_")
nms <- str_to_lower(nms)
names(raw) <- nms
# quedarnos con Estado y Total
df <- raw %>%
select(Estado = entidad_federativa, Total = total) %>%
mutate(Estado = as.character(Estado),
Total = suppressWarnings(as.numeric(Total))) %>%
filter(!is.na(Estado), !is.na(Total)) %>%
filter(!grepl("^total$", Estado, TRUE),
!grepl("estados\\s+unidos\\s+mexicanos", Estado, TRUE))
head(df)
## # A tibble: 6 × 2
## Estado Total
## <chr> <dbl>
## 1 Aguascalientes 756781
## 2 Baja California 2404000
## 3 Baja California Sur 624470
## 4 Campeche 404759
## 5 Chiapas 1231890
## 6 Chihuahua 1879130
variable_base <- "Total" # no hay población en este archivo
x <- scale(df[[variable_base]])
mat <- as.matrix(x) # para factoextra y dist
fviz_nbclust(mat, kmeans, method="wss") + ggtitle("Método del codo (WSS)")
fviz_nbclust(mat, kmeans, method="silhouette") + ggtitle("Coeficiente de silueta")
if (!exists("k_elegido")) k_elegido <- 3
k_elegido
## [1] 3
set.seed(123)
km <- kmeans(mat, centers = k_elegido, nstart = 50)
df_km <- df %>% mutate(cluster_kmeans = factor(km$cluster))
km$centers
## [,1]
## 1 -0.4435732
## 2 3.3224750
## 3 0.2966763
df_km %>% arrange(cluster_kmeans, .data[[variable_base]])
## # A tibble: 32 × 3
## Estado Total cluster_kmeans
## <chr> <dbl> <fct>
## 1 Campeche 404759 1
## 2 Colima 427510 1
## 3 Nayarit 556713 1
## 4 Baja California Sur 624470 1
## 5 Tlaxcala 638165 1
## 6 Hidalgo 707339 1
## 7 Zacatecas 736225 1
## 8 Aguascalientes 756781 1
## 9 Durango 765038 1
## 10 Tabasco 798316 1
## # ℹ 22 more rows
df_plot <- df_km %>%
arrange(.data[[variable_base]]) %>%
mutate(Estado = factor(Estado, levels = Estado))
ggplot(df_plot, aes(x = Estado, y = .data[[variable_base]], fill = cluster_kmeans)) +
geom_col() + coord_flip() +
labs(title = "Total de vehículos por estado (clusters K-means)",
x = "Estado", y = "Total de vehículos", fill = "Cluster") +
theme_minimal()
ggplot(df_km, aes(x = cluster_kmeans, y = .data[[variable_base]], fill = cluster_kmeans)) +
geom_boxplot(alpha=.85) +
labs(title = "Distribución por cluster (K-means)",
x = "Cluster", y = "Total de vehículos") +
theme_minimal() + guides(fill="none")
# Checa el tamaño y si hay problemas de NA/duplicados
nrow(df); length(unique(df$Estado))
## [1] 32
## [1] 32
summary(df$Total)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 404759 762974 1263658 1818728 1925416 9988109
sum(!is.finite(df$Total))
## [1] 0
head(df, 10)
## # A tibble: 10 × 2
## Estado Total
## <chr> <dbl>
## 1 Aguascalientes 756781
## 2 Baja California 2404000
## 3 Baja California Sur 624470
## 4 Campeche 404759
## 5 Chiapas 1231890
## 6 Chihuahua 1879130
## 7 Ciudad de México 6471738
## 8 Coahuila de Zaragoza 1257493
## 9 Colima 427510
## 10 Durango 765038
# Crear df_fix a partir de df
df_fix <- df # o el nombre de tu dataset original
cat("Número de estados en df_fix:", nrow(df_fix), "\n")
## Número de estados en df_fix: 32
print(df_fix)
## # A tibble: 32 × 2
## Estado Total
## <chr> <dbl>
## 1 Aguascalientes 756781
## 2 Baja California 2404000
## 3 Baja California Sur 624470
## 4 Campeche 404759
## 5 Chiapas 1231890
## 6 Chihuahua 1879130
## 7 Ciudad de México 6471738
## 8 Coahuila de Zaragoza 1257493
## 9 Colima 427510
## 10 Durango 765038
## # ℹ 22 more rows
# 1) Usa el data frame correcto
df <- df_fix # asegúrate de apuntar al df que sí tiene los 32 estados
# 2) Limpieza por si acaso
df <- df |>
dplyr::filter(!is.na(Total), is.finite(Total)) |>
dplyr::mutate(Estado = trimws(Estado)) |>
dplyr::distinct(Estado, .keep_all = TRUE)
# 3) Verificación
cat("Filas válidas:", nrow(df), "\n") # Debe ser >= 2 (ideal: 32)
## Filas válidas: 32
print(head(df, 10))
## # A tibble: 10 × 2
## Estado Total
## <chr> <dbl>
## 1 Aguascalientes 756781
## 2 Baja California 2404000
## 3 Baja California Sur 624470
## 4 Campeche 404759
## 5 Chiapas 1231890
## 6 Chihuahua 1879130
## 7 Ciudad de México 6471738
## 8 Coahuila de Zaragoza 1257493
## 9 Colima 427510
## 10 Durango 765038
# 4) Matriz 1-columna + nombres de fila
mat <- as.matrix(df$Total)
rownames(mat) <- df$Estado
# 5) Heatmap (solo clusteriza FILAS; no columnas)
if (!require(pheatmap)) install.packages("pheatmap")
## Cargando paquete requerido: pheatmap
library(pheatmap)
pheatmap(
mat,
scale = "column", # correcto para 1 variable
cluster_rows = TRUE, # dendrograma de estados
cluster_cols = FALSE, # no intentes clusterizar columnas (solo hay 1)
clustering_method = "ward.D2",
main = "Mapa de calor con dendrograma — Clustering jerárquico",
color = colorRampPalette(c("blue","white","red"))(50),
fontsize_row = 8
)
# Conclusiones del análisis
d <- dist(mat, method = "euclidean")
hc <- hclust(d, method = "complete")
plot(hc, main = "Dendrograma - Clustering jerárquico", xlab = "Estados")
rect.hclust(hc, k = k_elegido, border = "red")
df_hc <- df %>% mutate(cluster_hclust = factor(cutree(hc, k = k_elegido)))
df_hc %>% arrange(cluster_hclust, .data[[variable_base]])
## # A tibble: 32 × 3
## Estado Total cluster_hclust
## <chr> <dbl> <fct>
## 1 Campeche 404759 1
## 2 Colima 427510 1
## 3 Nayarit 556713 1
## 4 Baja California Sur 624470 1
## 5 Tlaxcala 638165 1
## 6 Hidalgo 707339 1
## 7 Zacatecas 736225 1
## 8 Aguascalientes 756781 1
## 9 Durango 765038 1
## 10 Tabasco 798316 1
## # ℹ 22 more rows