Contexto

La base de datos USArrests contiene estadísticas en arrestos por cada 100,000 residentes por agresión, asesinato y violación en cada uno de los 50 estados de E.E.U.U. en 1973.

Instalar paquetes y llamar paqueterias

#install.packages("cluster") #Para agrupar
library(cluster)
#install.packages("ggplot2") #Para graficar
library(ggplot2)
#install.packages("factoextra") #Visualizar clusters
library(factoextra)
#install.packages("data.table") #Conjunto de datos grandes
library(data.table)
#install.packages("tidyverse")
library(tidyverse)

Importar base de datos

df <- USArrests

Escalar la base

df <- df[, c("Murder", "Assault", "Rape")]
df <- na.omit(df)
datos_escalados <- scale(df)
grupos <- 3 
segmentos <- kmeans(datos_escalados, grupos)

Asignar grupos a datos

asignacion <- cbind(df,  cluster = segmentos$cluster)

Graficar cluster

fviz_cluster(segmentos, data=df)

Optimizar la cantidad de grupos

# La cantidad optima de grupos corresponde al primer punto mas alto de la grafica
set.seed(123)
optimizacion <- clusGap(datos_escalados, FUN=kmeans, nstart=1, K.max=7)
plot(optimizacion, xlab="Numero de clusters", main= "Metodo de la silueta")

#El K optimo es el coeficiente de silueta maximo
fviz_nbclust(df, kmeans, method = "wss") +
  ggtitle("Metodo del Codo")

#El K optimo es el coeficiente de silueta del punto de inflexion

Asignar cluster

promedio <- aggregate(asignacion, by=list(asignacion$cluster),FUN=mean)
promedio
##   Group.1    Murder   Assault     Rape cluster
## 1       1  3.078571  80.92857 11.80000       1
## 2       2 12.331579 259.31579 29.21579       2
## 3       3  6.588235 145.76471 20.07647       3
table(asignacion$cluster)
## 
##  1  2  3 
## 14 19 17

Nuevas librerias

#install.packages("sf") #Analisis de datos espaciales
library(sf)
#install.packages("rnaturalearth") #Proporcioa limites geograficos
library(rnaturalearth)
#install.packages("rnaturalearthdata") #Datos de geografia
library(rnaturalearthdata)
#install.packages("devtools")
library(devtools) #Instalar paquetes de fuentes externas
devtools::install_github("ropensci/rnaturalearthhires") #Mapa de Mexico particular

Obtener mapa de Estados unidos

usa <- ne_states(country = "United States of America", returnclass = "sf")

Fijar semilla para reproducibilidad

set.seed(123)  # Fijar semilla para reproducibilidad
kmeans_result <- kmeans(datos_escalados, centers = 3, nstart = 25)
df$Cluster <- as.factor(kmeans_result$cluster)  # Agregar la asignación de cluster al dataframe
aggregate(df[, 1:4], by = list(df$Cluster), mean)
## Warning in mean.default(X[[i]], ...): argument is not numeric or logical:
## returning NA
## Warning in mean.default(X[[i]], ...): argument is not numeric or logical:
## returning NA
## Warning in mean.default(X[[i]], ...): argument is not numeric or logical:
## returning NA
##   Group.1    Murder   Assault     Rape Cluster
## 1       1 12.331579 259.31579 29.21579      NA
## 2       2  6.588235 145.76471 20.07647      NA
## 3       3  3.078571  80.92857 11.80000      NA

Establecer numero y nombre de Clusters

df$Seguridad <- factor(df$Cluster, 
                       levels = c(1, 2, 3), 
                       labels = c("Muy Seguro", "Seguro", "No Seguro"))

Generacion de mapa con Cluster

# Unir el dataset con el mapa
usa$state_name <- tolower(usa$name)  # Convertir nombres de estados a minúsculas
df$state_name <- tolower(rownames(df))  # Lo mismo para la base de datos

usa_map <- left_join(usa, df, by = "state_name")

# Graficar el mapa con los clusters
ggplot(data = usa_map) +
  geom_sf(aes(fill = Seguridad)) +
  scale_fill_manual(values = c("Muy Seguro" = "green", 
                               "Seguro" = "yellow",
                               "No Seguro" = "red")) +
  ggtitle("Clusters de seguridad en EE.UU. (USArrests)") +
  theme_minimal()

LS0tCnRpdGxlOiAiVVNBcnJlc3RzIgphdXRob3I6ICJEaWVnbyBkZSBsYSBHYXJ6YSAtIEEwMTcyMjM2NSIKZGF0ZTogIjIwMjUtMDItMjEiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiBUUlVFCiAgICB0b2NfZmxvYXQ6IFRSVUUKICAgIGNvZGVfZG93bmxvYWQ6IFRSVUUKICAgIHRoZW1lOiBqb3VybmFsCiAgICBoaWdobGlnaHQ6ICJlc3ByZXNzbyIKLS0tCgohW10oL1VzZXJzL2RpZWdvL0Rlc2t0b3AvQ29uY2VudHJhY2lvzIFuL3B1cmdlLnBuZykKCiMgPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQ7Ij5Db250ZXh0bzwvc3Bhbj4KTGEgYmFzZSBkZSBkYXRvcyAqVVNBcnJlc3RzKiBjb250aWVuZSBlc3RhZMOtc3RpY2FzIGVuIGFycmVzdG9zIHBvciBjYWRhIDEwMCwwMDAgcmVzaWRlbnRlcyBwb3IgYWdyZXNpw7NuLCBhc2VzaW5hdG8geSB2aW9sYWNpw7NuIGVuIGNhZGEgdW5vIGRlIGxvcyA1MCBlc3RhZG9zIGRlIEUuRS5VLlUuIGVuIDE5NzMuCgojIDxzcGFuIHN0eWxlID0iY29sb3I6IHJlZDsiPkluc3RhbGFyIHBhcXVldGVzIHkgbGxhbWFyIHBhcXVldGVyaWFzPC9zcGFuPgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojaW5zdGFsbC5wYWNrYWdlcygiY2x1c3RlciIpICNQYXJhIGFncnVwYXIKbGlicmFyeShjbHVzdGVyKQojaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpICNQYXJhIGdyYWZpY2FyCmxpYnJhcnkoZ2dwbG90MikKI2luc3RhbGwucGFja2FnZXMoImZhY3RvZXh0cmEiKSAjVmlzdWFsaXphciBjbHVzdGVycwpsaWJyYXJ5KGZhY3RvZXh0cmEpCiNpbnN0YWxsLnBhY2thZ2VzKCJkYXRhLnRhYmxlIikgI0Nvbmp1bnRvIGRlIGRhdG9zIGdyYW5kZXMKbGlicmFyeShkYXRhLnRhYmxlKQojaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikKbGlicmFyeSh0aWR5dmVyc2UpCmBgYAoKIyA8c3BhbiBzdHlsZSA9ImNvbG9yOiByZWQ7Ij5JbXBvcnRhciBiYXNlIGRlIGRhdG9zPC9zcGFuPgpgYGB7cn0KZGYgPC0gVVNBcnJlc3RzCmBgYAoKIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQ7Ij5Fc2NhbGFyIGxhIGJhc2U8L3NwYW4+CmBgYHtyfQpkZiA8LSBkZlssIGMoIk11cmRlciIsICJBc3NhdWx0IiwgIlJhcGUiKV0KZGYgPC0gbmEub21pdChkZikKZGF0b3NfZXNjYWxhZG9zIDwtIHNjYWxlKGRmKQpgYGAKCmBgYHtyfQpncnVwb3MgPC0gMyAKc2VnbWVudG9zIDwtIGttZWFucyhkYXRvc19lc2NhbGFkb3MsIGdydXBvcykKYGBgCgojIyA8c3BhbiBzdHlsZT0iY29sb3I6IHJlZDsiPkFzaWduYXIgZ3J1cG9zIGEgZGF0b3M8L3NwYW4+CmBgYHtyfQphc2lnbmFjaW9uIDwtIGNiaW5kKGRmLCAgY2x1c3RlciA9IHNlZ21lbnRvcyRjbHVzdGVyKQpgYGAKCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjogcmVkOyI+R3JhZmljYXIgY2x1c3Rlcjwvc3Bhbj4KYGBge3J9CmZ2aXpfY2x1c3RlcihzZWdtZW50b3MsIGRhdGE9ZGYpCmBgYAoKIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQ7Ij5PcHRpbWl6YXIgbGEgY2FudGlkYWQgZGUgZ3J1cG9zPC9zcGFuPgpgYGB7cn0KIyBMYSBjYW50aWRhZCBvcHRpbWEgZGUgZ3J1cG9zIGNvcnJlc3BvbmRlIGFsIHByaW1lciBwdW50byBtYXMgYWx0byBkZSBsYSBncmFmaWNhCnNldC5zZWVkKDEyMykKb3B0aW1pemFjaW9uIDwtIGNsdXNHYXAoZGF0b3NfZXNjYWxhZG9zLCBGVU49a21lYW5zLCBuc3RhcnQ9MSwgSy5tYXg9NykKcGxvdChvcHRpbWl6YWNpb24sIHhsYWI9Ik51bWVybyBkZSBjbHVzdGVycyIsIG1haW49ICJNZXRvZG8gZGUgbGEgc2lsdWV0YSIpCiNFbCBLIG9wdGltbyBlcyBlbCBjb2VmaWNpZW50ZSBkZSBzaWx1ZXRhIG1heGltbwpmdml6X25iY2x1c3QoZGYsIGttZWFucywgbWV0aG9kID0gIndzcyIpICsKICBnZ3RpdGxlKCJNZXRvZG8gZGVsIENvZG8iKQojRWwgSyBvcHRpbW8gZXMgZWwgY29lZmljaWVudGUgZGUgc2lsdWV0YSBkZWwgcHVudG8gZGUgaW5mbGV4aW9uCmBgYAoKIyA8c3BhbiBzdHlsZSA9ImNvbG9yOiByZWQ7Ij5Bc2lnbmFyIGNsdXN0ZXI8L3NwYW4+CmBgYHtyfQpwcm9tZWRpbyA8LSBhZ2dyZWdhdGUoYXNpZ25hY2lvbiwgYnk9bGlzdChhc2lnbmFjaW9uJGNsdXN0ZXIpLEZVTj1tZWFuKQpwcm9tZWRpbwp0YWJsZShhc2lnbmFjaW9uJGNsdXN0ZXIpCmBgYAoKIyA8c3BhbiBzdHlsZSA9ImNvbG9yOiByZWQ7Ij5OdWV2YXMgbGlicmVyaWFzPC9zcGFuPgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojaW5zdGFsbC5wYWNrYWdlcygic2YiKSAjQW5hbGlzaXMgZGUgZGF0b3MgZXNwYWNpYWxlcwpsaWJyYXJ5KHNmKQojaW5zdGFsbC5wYWNrYWdlcygicm5hdHVyYWxlYXJ0aCIpICNQcm9wb3JjaW9hIGxpbWl0ZXMgZ2VvZ3JhZmljb3MKbGlicmFyeShybmF0dXJhbGVhcnRoKQojaW5zdGFsbC5wYWNrYWdlcygicm5hdHVyYWxlYXJ0aGRhdGEiKSAjRGF0b3MgZGUgZ2VvZ3JhZmlhCmxpYnJhcnkocm5hdHVyYWxlYXJ0aGRhdGEpCiNpbnN0YWxsLnBhY2thZ2VzKCJkZXZ0b29scyIpCmxpYnJhcnkoZGV2dG9vbHMpICNJbnN0YWxhciBwYXF1ZXRlcyBkZSBmdWVudGVzIGV4dGVybmFzCmRldnRvb2xzOjppbnN0YWxsX2dpdGh1Yigicm9wZW5zY2kvcm5hdHVyYWxlYXJ0aGhpcmVzIikgI01hcGEgZGUgTWV4aWNvIHBhcnRpY3VsYXIKYGBgCgojIDxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIDsiPk9idGVuZXIgbWFwYSBkZSBFc3RhZG9zIHVuaWRvczwvc3Bhbj4KYGBge3J9CnVzYSA8LSBuZV9zdGF0ZXMoY291bnRyeSA9ICJVbml0ZWQgU3RhdGVzIG9mIEFtZXJpY2EiLCByZXR1cm5jbGFzcyA9ICJzZiIpCmBgYAoKIyA8c3BhbiBzdHlsZSA9ImNvbG9yOiByZWQ7Ij5GaWphciBzZW1pbGxhIHBhcmEgcmVwcm9kdWNpYmlsaWRhZDwvc3Bhbj4KYGBge3J9CnNldC5zZWVkKDEyMykgICMgRmlqYXIgc2VtaWxsYSBwYXJhIHJlcHJvZHVjaWJpbGlkYWQKa21lYW5zX3Jlc3VsdCA8LSBrbWVhbnMoZGF0b3NfZXNjYWxhZG9zLCBjZW50ZXJzID0gMywgbnN0YXJ0ID0gMjUpCmBgYAoKYGBge3J9CmRmJENsdXN0ZXIgPC0gYXMuZmFjdG9yKGttZWFuc19yZXN1bHQkY2x1c3RlcikgICMgQWdyZWdhciBsYSBhc2lnbmFjacOzbiBkZSBjbHVzdGVyIGFsIGRhdGFmcmFtZQpgYGAKCmBgYHtyfQphZ2dyZWdhdGUoZGZbLCAxOjRdLCBieSA9IGxpc3QoZGYkQ2x1c3RlciksIG1lYW4pCmBgYAoKIyA8c3BhbiBzdHlsZSA9ImNvbG9yOiByZWQ7Ij5Fc3RhYmxlY2VyIG51bWVybyAgeSBub21icmUgZGUgQ2x1c3RlcnM8L3NwYW4+CmBgYHtyfQpkZiRTZWd1cmlkYWQgPC0gZmFjdG9yKGRmJENsdXN0ZXIsIAogICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoMSwgMiwgMyksIAogICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIk11eSBTZWd1cm8iLCAiU2VndXJvIiwgIk5vIFNlZ3VybyIpKQpgYGAKCiMgPHNwYW4gc3R5bGUgPSJjb2xvcjogcmVkOyI+R2VuZXJhY2lvbiBkZSBtYXBhIGNvbiBDbHVzdGVyPC9zcGFuPgpgYGB7cn0KIyBVbmlyIGVsIGRhdGFzZXQgY29uIGVsIG1hcGEKdXNhJHN0YXRlX25hbWUgPC0gdG9sb3dlcih1c2EkbmFtZSkgICMgQ29udmVydGlyIG5vbWJyZXMgZGUgZXN0YWRvcyBhIG1pbsO6c2N1bGFzCmRmJHN0YXRlX25hbWUgPC0gdG9sb3dlcihyb3duYW1lcyhkZikpICAjIExvIG1pc21vIHBhcmEgbGEgYmFzZSBkZSBkYXRvcwoKdXNhX21hcCA8LSBsZWZ0X2pvaW4odXNhLCBkZiwgYnkgPSAic3RhdGVfbmFtZSIpCgojIEdyYWZpY2FyIGVsIG1hcGEgY29uIGxvcyBjbHVzdGVycwpnZ3Bsb3QoZGF0YSA9IHVzYV9tYXApICsKICBnZW9tX3NmKGFlcyhmaWxsID0gU2VndXJpZGFkKSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIk11eSBTZWd1cm8iID0gImdyZWVuIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2VndXJvIiA9ICJ5ZWxsb3ciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vIFNlZ3VybyIgPSAicmVkIikpICsKICBnZ3RpdGxlKCJDbHVzdGVycyBkZSBzZWd1cmlkYWQgZW4gRUUuVVUuIChVU0FycmVzdHMpIikgKwogIHRoZW1lX21pbmltYWwoKQoKYGBgCgoKCgoKCgoKCgoKCgo=