El presente informe detalla un análisis multidimensional del mercado de viviendas de la ciudad, basado en la base de datos proporcionada. El objetivo principal fue obtener una comprensión profunda de las dinámicas del mercado para guiar decisiones estratégicas. Los resultados clave revelan la existencia de segmentos de mercado bien definidos y la influencia de factores como el tamaño y lujo de las propiedades, así como su ubicación y estrato socioeconómico. Estas conclusiones permiten a la empresa optimizar sus estrategias de inversión y ventas en un entorno competitivo.
El proceso de análisis comenzó con una exhaustiva exploración del conjunto de datos. Se identificaron los siguientes desafíos de calidad de datos, que se abordaron con los siguientes métodos:
Datos Faltantes: Se evidenció la presencia de datos faltantes en varios campos, siendo los más significativos las columnas de piso y parqueaderos, con un 31.7% y 19.29% de valores nulos, respectivamente. Para un manejo robusto, se utilizó la metodología MICE (Multiple Imputation by Chained Equations) para imputar estos valores. Se tomó el valor de la tercera iteración para asegurar una estimación precisa. Para el resto de los campos con un número menor de valores faltantes (aproximadamente un 4% del total), se optó por eliminar los registros correspondientes.
Problemas de Estandarización: Se detectaron problemas de digitación y formato, como el uso de caracteres especiales y mayúsculas inconsistentes. Para estandarizar los datos, se eliminaron los caracteres especiales, se unificó la escritura a minúsculas y se corrigieron los nombres de los barrios con un alto porcentaje de similitud para consolidar registros (ej. alférez y alferez).
Este proceso de limpieza y preparación aseguró la integridad del conjunto de datos, permitiendo que los siguientes análisis sean fiables y robustos.
# ---- 1. Se carga el dataset en una variable para ser usada y procesada en R
data("vivienda")
# --- 2. Se preparan los datos para la tabla resumen inicial ---
# Se obtiene la estructura del dataframe
col_names <- names(vivienda)
col_types <- sapply(vivienda, class)
col_counts <- sapply(vivienda, function(x) sum(!is.na(x)))
# Se calcula la cantidad y el porcentaje de valores faltantes por columna
total_faltantes <- sapply(vivienda, function(x) sum(is.na(x)))
porcentaje_faltantes <- sapply(vivienda, function(x) round(mean(is.na(x)) * 100, 2))
# Se consolida la informacion en un dataframe
tabla_final <- data.frame(
Nombre = col_names,
Tipo = col_types,
Conteo = col_counts,
Total_Faltantes = total_faltantes,
Porcentaje_Faltantes = porcentaje_faltantes
)
# --- 3. Se visualiza la tabla con kable y ajuste de estilo ---
kable(
tabla_final,
caption = "Tabla 1. Información de columnas Dataset Vivienda",
col.names = c("Nombre", "Tipo", "Conteo", "Total Faltantes", "Porcentaje (%)"),
format = "html",
align = c("l", "l", "c", "c", "c"),
row.names = FALSE
) %>%
kable_styling(
full_width = FALSE,
bootstrap_options = c("striped", "hover", "responsive"),
position = "center",
font_size = 12,
row_label_position = "c"
) %>%
column_spec(1, width = "1in") %>%
column_spec(2, width = "1in") %>%
column_spec(3, width = "1in") %>%
column_spec(4, width = "1in") %>%
column_spec(5, width = "1in") %>%
row_spec(0, bold = TRUE, color = "white", background = "#2C3E50")
Nombre | Tipo | Conteo | Total Faltantes | Porcentaje (%) |
---|---|---|---|---|
id | numeric | 8319 | 3 | 0.04 |
zona | character | 8319 | 3 | 0.04 |
piso | character | 5684 | 2638 | 31.70 |
estrato | numeric | 8319 | 3 | 0.04 |
preciom | numeric | 8320 | 2 | 0.02 |
areaconst | numeric | 8319 | 3 | 0.04 |
parqueaderos | numeric | 6717 | 1605 | 19.29 |
banios | numeric | 8319 | 3 | 0.04 |
habitaciones | numeric | 8319 | 3 | 0.04 |
tipo | character | 8319 | 3 | 0.04 |
barrio | character | 8319 | 3 | 0.04 |
longitud | numeric | 8319 | 3 | 0.04 |
latitud | numeric | 8319 | 3 | 0.04 |
# --- 4. Se inicia con el tratamiento de los datos ---
# --- 4.1. Normalización de caracteres para disminuir el error tipografico y humano ---
# Se realiza eliminación de caracteres especiales y normalización de tildes
vivienda$barrio <- gsub("[^a-zA-ZáéíóúÁÉÍÓÚñÑ ]", "", vivienda$barrio)
vivienda$barrio <- chartr("áéíóúÁÉÍÓÚ", "aeiouAEIOU", vivienda$barrio)
# Se transformar la columna piso de tipo caracter a tipo númerica
vivienda <- vivienda %>%
# Se hace uso de la función as.numeric()
mutate(piso = as.numeric(piso))
# Se Identificar las columnas de tipo carácter y se convierte a minúsculas todos los caracteres
chr_cols <- sapply(vivienda, is.character)
vivienda[chr_cols] <- lapply(vivienda[chr_cols], tolower)
# Se elimina filas duplicadas
vivienda <- vivienda[!duplicated(vivienda), ]
# Se Elimina filas con valores faltantes en columnas con pocos datos perdidos
vivienda <- vivienda %>%
filter(!is.na(id))
# ===============================================================================================================
# Posterior de tener todos los campos con un estandar de digitación. Se decidé que se van a unificar barrios
# por similitud se van a tratar los barrios que tengan menos de 5 valores y se reemplazara el barrio con el texto
# más parecido, por ejemplo si tenemos alfrez sera reemplazado por alferez
# --- 4.2. Unificación de barrios con pocos registros ---
# Se calcula el conteo de cada barrio
barrio_counts <- vivienda %>%
group_by(barrio) %>%
summarise(conteo = n())
# Se divide los barrios en dos grupos: con conteo bajo y con conteo alto
low_count_barrios <- barrio_counts %>%
filter(conteo < 5) %>%
pull(barrio)
high_count_barrios <- barrio_counts %>%
filter(conteo >= 5) %>%
pull(barrio)
# Se registran los cambios en el siguiente dataframe
cambios_registrados <- data.frame(
barrio_original = character(),
barrio_unificado = character(),
distancia = numeric()
)
# Se inicia con la iteración de los barrios con conteo bajo y se busca el más similar
# Iterar sobre los barrios con conteo bajo y buscar el más similar
for (low_barrio in low_count_barrios) {
# Calcular la distancia de Levenshtein a todos los barrios de conteo alto
distancias <- stringdist(low_barrio, high_count_barrios, method = "lv")
# Encontrar el índice del barrio con la distancia mínima
min_dist_index <- which.min(distancias)
# Obtener el nombre del barrio más similar
similar_barrio <- high_count_barrios[min_dist_index]
# Registrar el cambio
cambios_registrados <- cambios_registrados %>%
add_row(barrio_original = low_barrio,
barrio_unificado = similar_barrio,
distancia = min(distancias))
# Unificar el nombre del barrio en el dataframe principal
vivienda$barrio[vivienda$barrio == low_barrio] <- similar_barrio
}
# --- 5. Se realiza la imputación de datos faltantes con la metodología MICE ---
# Se debe tener en cuenta que las variables de tipo 'object' en python, son 'character' en R.
# Sin embargo, mice requiere que las variables sean factores.
vivienda$zona <- as.factor(vivienda$zona)
vivienda$tipo <- as.factor(vivienda$tipo)
vivienda$barrio <- as.factor(vivienda$barrio)
# Se ejecuta el algoritmo MICE (genera 5 imputaciones por defecto)
# Se usa un seed para asegurar la reproducibilidad de los resultados
set.seed(123)
imputacion_mice <- mice(vivienda, m = 5, method = 'cart', printFlag = FALSE)
Warning: Number of logged events: 50
# Se completa el dataframe con la tercera imputación
vivienda_mice <- complete(imputacion_mice, 3)
En el análisis del PCA se realizará los siguientes pasos:
Seleccionar variables: Se utilizarán las variables numéricas clave (estrato, preciom, areaconst, parqueaderos, banios y habitaciones).
Estandarizar los datos: Se escalarán las variables para que tengan una media de 0 y una desviación estándar de 1, lo cual es un requisito crucial para el PCA.
Aplicar PCA: Se aplicará el algoritmo de PCA a las variables estandarizadas.
Visualizar la varianza: Se generará un gráfico de la varianza explicada por cada componente para determinar cuántos componentes principales son necesarios para capturar la mayor parte de la información.
Esto nos permitirá entender la estructura subyacente de los datos y cómo las variables se relacionan entre sí en un espacio de menor dimensión.
# ---- 1. Se selecciona las variables numéricas para el PCA
# Tener en cuenta que, las variables son: estrato, preciom, areaconst, parqueaderos, banios, habitaciones
# Para evitar errores se convierte la variable 'estrato' a numérica
numerical_features <- vivienda_mice %>%
select(estrato, preciom, areaconst, parqueaderos, banios, habitaciones) %>%
mutate(estrato = as.numeric(estrato))
# ---- 2. Se realiza el Análisis de Componentes Principales (PCA)
# Se hace uso de la función PCA() de la librería FactoMineR.
# scale.unit = TRUE estandariza los datos automáticamente.
# ncp = 6 especifica que queremos 6 componentes principales.
res.pca <- PCA(numerical_features, graph = FALSE, ncp = 6)
# ---- 3. Se visualiza los resultados del PCA
# 3.a. Gráfico de la varianza explicada (Scree Plot)
# Este gráfico ayuda a decidir cuántos componentes retener
fviz_eig(res.pca, addlabels = TRUE, ylim = c(0, 70),
main = "Varianza Explicada por Componentes Principales")
# 3.b. Se visualiza los individuos (propiedades) en los primeros dos componentes
# Se hace uso fviz_pca_ind() de factoextra para este gráfico
# coloreamos por 'tipo' y usamos la forma de 'zona'
# Para esto, necesitamos combinar los datos de PCA con las variables categóricas
vivienda_pca <- res.pca$ind$coord %>%
as.data.frame() %>%
rownames_to_column(var = "id") %>%
as_tibble() %>%
mutate(tipo = vivienda_mice$tipo,
zona = vivienda_mice$zona)
# Graficar los individuos
ggplot(vivienda_pca, aes(x = Dim.1, y = Dim.2, color = tipo, shape = zona)) +
geom_point(alpha = 0.6) +
labs(title = "Gráfico de los Dos Primeros Componentes Principales",
x = "Componente Principal 1",
y = "Componente Principal 2",
color = "Tipo de Propiedad",
shape = "Zona") +
theme_minimal() +
scale_color_viridis_d() # Para una paleta de colores atractiva
# 3.c. Biplot - Visualización de individuos y variables
# Este gráfico combina los puntos de las propiedades con los vectores de las variables originales.
# Permite interpretar la relación entre las variables y cómo influyen en los componentes.
fviz_pca_biplot(res.pca,
label = "var", # Muestra las etiquetas de las variables
habillage = vivienda_mice$tipo, # Colorea los puntos por 'tipo'
title = "Biplot de PCA",
geom.ind = "point", # Muestra los individuos como puntos
geom.var = "arrow", # Muestra las variables como flechas
col.var = "black" # Color de las flechas
)
# ---- 4. Se obtiene y se visualiza la matriz de cargas (loadings)
# Las cargas de los componentes se encuentran en la matriz de componentes
loadings_matrix <- res.pca$var$contrib
# ---- 4.1. Convertir la matriz en un data frame para kable
# Se agrega una columna para los nombres de las variables
loadings_df <- as.data.frame(loadings_matrix)
loadings_df <- data.frame(Variable = rownames(loadings_df), loadings_df, row.names = NULL)
# ---- 4.2. Se visualiza la tabla con kable y ajuste de estilo
kable(
loadings_df,
caption = "Tabla 2. Contribución de las Variables a los Componentes Principales",
format = "html",
align = c("l", rep("c", ncol(loadings_df) - 1)),
digits = 2,
row.names = FALSE
) %>%
kable_styling(
full_width = FALSE,
bootstrap_options = c("striped", "hover", "responsive"),
position = "center",
font_size = 12,
row_label_position = "c"
) %>%
column_spec(1, bold = TRUE) %>% # Pone en negrita la columna de las variables
column_spec(2:(ncol(loadings_df)), width = "1in") %>%
row_spec(0, bold = TRUE, color = "white", background = "#2C3E50")
Variable | Dim.1 | Dim.2 | Dim.3 | Dim.4 | Dim.5 | Dim.6 |
---|---|---|---|---|---|---|
estrato | 9.71 | 37.84 | 29.18 | 0.00 | 20.02 | 3.26 |
preciom | 22.47 | 5.29 | 1.33 | 6.07 | 3.82 | 61.02 |
areaconst | 19.80 | 4.33 | 11.27 | 43.22 | 4.19 | 17.18 |
parqueaderos | 18.39 | 2.58 | 31.88 | 43.54 | 1.20 | 2.42 |
banios | 21.27 | 2.90 | 16.43 | 1.76 | 48.51 | 9.14 |
habitaciones | 8.36 | 47.07 | 9.91 | 5.40 | 22.27 | 6.99 |
Resumen del Biplot:
Las propiedades que se encuentran en el lado derecho del gráfico (valores altos de PC1) son probablemente propiedades de lujo o grandes, con precios altos y una gran área de construcción.
Las propiedades en la parte superior del gráfico (valores altos de PC2) son aquellas con un alto número de baños y habitaciones, que podrían ser propiedades familiares o de uso comercial.
Resumen Matriz:
La Mayoría de la Varianza está en los Primeros Componentes: Los primeros dos componentes principales (PC1 y PC2) explican conjuntamente el 74.6% de la variabilidad total de los datos.
PC1 es el Componente más Dominante: El Componente Principal 1 (PC1) es el más importante de todos, ya que por sí solo explica el 42.1% de la varianza.
Se Requieren Más de Dos Componentes para una Representación Completa: Aunque el PC1 y PC2 son los más significativos, el 35.4% de la varianza total de los datos sigue sin ser explicada por ellos.
Seis Componentes para Explicar el 100%: El análisis muestra un total de 6 componentes principales, lo que es igual al número de variables numéricas originales que se utilizaron en el análisis. Juntos, estos 6 componentes explican el 100% de la varianza total, lo cual es matemáticamente consistente.
El análisis de conglomerados se llevó a cabo para agrupar las propiedades en segmentos homogéneos basándose en sus características numéricas. El proceso incluyó los siguientes pasos clave:
Preparación y Estandarización de Datos: Se seleccionaron las variables numéricas clave (estrato, preciom, areaconst, parqueaderos, banios, habitaciones). Para asegurar que todas las variables contribuyeran por igual, se estandarizaron los datos (se centraron en cero y se escalaron a la unidad) antes de aplicar el algoritmo.
Determinación del Número Óptimo de Clústeres: Se utilizó el método del codo para determinar el número ideal de segmentos. El análisis visual del gráfico sugirió que el valor óptimo de clústeres es 3, ya que en este punto la inercia (la suma de las distancias cuadradas) deja de disminuir significativamente.
Aplicación del Algoritmo y Resumen de Resultados: El algoritmo K-Means se ejecutó con 3 clústeres. Posteriormente, se calculó la media de cada una de las variables numéricas para cada clúster, lo que permitió definir las características de cada uno de los tres segmentos de mercado identificados. Esta información se presentó en una tabla formateada para facilitar su interpretación.
# ---- 1. Se seleccionan las variables numéricas para el clustering
# Tener en cuenta que, las variables son: estrato, preciom, areaconst, parqueaderos, banios, habitaciones
# Para evitar errores se convierte la variable 'estrato' a numérica
numerical_features <- vivienda_mice %>%
select(estrato, preciom, areaconst, parqueaderos, banios, habitaciones) %>%
mutate(estrato = as.numeric(estrato))
# ---- 2. Estandarizar los datos (centrar y escalar)
# La función `scale()` de R hace esto de forma nativa
X_scaled <- scale(numerical_features)
# ---- 3. Determinar el número óptimo de clústeres usando el Método del Codo
# Usamos la función `fviz_nbclust` para automatizar el cálculo y la visualización.
fviz_nbclust(X_scaled, kmeans, method = "wss", k.max = 10) +
labs(title = "Método del Codo para K-Means") +
theme_minimal()
# Basado en el gráfico, el punto del codo se encuentra en k=3.
# Se define este como el número óptimo de clústeres.
optimal_k <- 3
print(paste("El número óptimo de clústeres es:", optimal_k))
[1] "El número óptimo de clústeres es: 3"
# ---- 4. Realizar el clustering con K-Means
set.seed(42) # Para reproducibilidad de los resultados
kmeans_result <- kmeans(X_scaled, centers = optimal_k, nstart = 25)
# ---- 5. Añadir la asignación de clústeres al dataset original
vivienda_mice$cluster <- as.factor(kmeans_result$cluster)
# ---- 6. Analizar las características de cada clúster
# Se calcula la media de las variables para cada grupo
cluster_summary <- vivienda_mice %>%
group_by(cluster) %>%
summarise(across(all_of(names(numerical_features)), mean))
# ---- 6.1. Se visualiza la tabla con kable y ajuste de estilo
kable(
cluster_summary,
caption = "Tabla 3. Características Promedio de los Clústeres",
format = "html",
align = c("l", rep("c", ncol(cluster_summary) - 1)),
digits = 2,
row.names = FALSE
) %>%
kable_styling(
full_width = FALSE,
bootstrap_options = c("striped", "hover", "responsive"),
position = "center",
font_size = 12,
row_label_position = "c"
) %>%
column_spec(1, bold = TRUE) %>% # Pone en negrita la columna de los clústeres
column_spec(2:(ncol(cluster_summary)), width = "1in") %>%
row_spec(0, bold = TRUE, color = "white", background = "#2C3E50")
cluster | estrato | preciom | areaconst | parqueaderos | banios | habitaciones |
---|---|---|---|---|---|---|
1 | 4.19 | 237.41 | 93.79 | 1.19 | 2.13 | 2.90 |
2 | 4.98 | 507.46 | 218.60 | 1.91 | 3.95 | 4.40 |
3 | 5.66 | 1102.41 | 414.68 | 3.76 | 5.13 | 4.54 |
# ---- 7. Visualizar los clústeres sobre los dos primeros componentes principales (PCA)
# Primero, realizamos un PCA para obtener las dos dimensiones principales
pca_result <- prcomp(X_scaled, center = TRUE, scale. = FALSE)
# Luego, usamos `fviz_cluster` para graficar los clústeres en estas dimensiones
fviz_cluster(
kmeans_result,
data = X_scaled,
geom = "point",
ellipse.type = "convex",
palette = "viridis",
main = paste("Visualización de los Clústeres (K=", optimal_k, ")")
) +
theme_minimal()
Conclusiones del Análisis de Conglomerados
Tres Segmentos de Mercado Claros: Los datos se han agrupado en tres conglomerados bien definidos, lo que sugiere que el mercado inmobiliario puede segmentarse en al menos tres tipos de propiedades con características distintivas. Esta segmentación es fundamental para la toma de decisiones.
Diferencia en el Tamaño de los Conglomerados:
Conglomerado 1 (Verde): Este es el segundo grupo más grande y denso, lo que podría representar la mayoría de las propiedades en el mercado. Es probable que se trate del segmento de viviendas “estándar” o de gama media.
Conglomerado 2 (Azul): Es el primer grupo más grande y disperso. Las propiedades en este segmento son distintas de las del conglomerado verde, lo que indica un tipo de oferta diferente, quizás de un estrato socioeconómico o tamaño ligeramente superior.
Conglomerado 3 (Rojo): Este es un grupo más pequeño y ligeramente disperso, lo que sugiere una mayor heterogeneidad dentro del mismo. Podría representar propiedades con características únicas o menos comunes, como viviendas de lujo o con atributos atípicos.
Evaluación del Clustering: La separación visual entre los conglomerados sugiere que el algoritmo K-Means ha hecho un buen trabajo al encontrar grupos homogéneos. Sin embargo, la dispersión del conglomerado azul indica que podría ser interesante analizar con más detalle si este grupo debería dividirse o redefinirse.
Para comprender la relación entre las variables categóricas zona (ubicación geográfica) y estrato (nivel socioeconómico), se aplicó la técnica de Análisis de Correspondencia (CA). Este método es ideal para visualizar las asociaciones entre las categorías de dos variables nominales.
El proceso se ejecutó en las siguientes fases:
Creación de la Tabla de Contingencia: Se preparó una tabla que resume la frecuencia de cada combinación de zona y estrato. Esta tabla, que se presenta en el informe, sirve como base para el análisis, mostrando la distribución de las propiedades en cada segmento.
Análisis de la Varianza: Se realizó el análisis de correspondencia, y se visualizó la varianza explicada por cada dimensión. Este gráfico (fviz_eig) ayuda a determinar la cantidad de dimensiones necesarias para representar la mayor parte de la variabilidad del dataset.
Generación del Biplot: Se extrajeron las coordenadas de los resultados del análisis para crear un biplot. Este gráfico es la pieza central del análisis, ya que permite visualizar la relación entre las categorías de las dos variables. En el biplot, las categorías que aparecen cerca unas de otras están fuertemente asociadas, mientras que las que están separadas tienen una asociación débil.
# 3. Preparar los datos: Crear una tabla de contingencia
# El Análisis de Correspondencia trabaja con variables categóricas.
# Se crea una tabla que resume la frecuencia de cada combinación de 'zona' y 'estrato'.
contingency_table <- table(vivienda_mice$zona, vivienda_mice$estrato)
# 4. Formatear y visualizar la tabla de contingencia con kable
contingency_df <- as.data.frame.matrix(contingency_table)
contingency_df <- data.frame(Zona = rownames(contingency_df), contingency_df, row.names = NULL)
kable(
contingency_df,
caption = "Tabla 4. Distribución de Propiedades por Zona y Estrato",
format = "html",
align = c("l", rep("c", ncol(contingency_df) - 1)),
row.names = FALSE
) %>%
kable_styling(
full_width = FALSE,
bootstrap_options = c("striped", "hover", "responsive"),
position = "center",
font_size = 12,
row_label_position = "c"
) %>%
column_spec(1, bold = TRUE) %>%
column_spec(2:(ncol(contingency_df)), width = "1in") %>%
row_spec(0, bold = TRUE, color = "white", background = "#2C3E50")
Zona | X3 | X4 | X5 | X6 |
---|---|---|---|---|
zona centro | 105 | 14 | 4 | 1 |
zona norte | 572 | 407 | 769 | 172 |
zona oeste | 54 | 84 | 290 | 770 |
zona oriente | 340 | 8 | 2 | 1 |
zona sur | 382 | 1616 | 1685 | 1043 |
# 5. Realizar el Análisis de Correspondencia (CA)
res.ca <- CA(contingency_table, graph = FALSE)
# 6. Visualizar los resultados del Análisis de Correspondencia
# a) Gráfico de la varianza explicada por las dimensiones
fviz_eig(res.ca, addlabels = TRUE, ylim = c(0, 100),
main = "Varianza Explicada por las Dimensiones")
# b) Biplot para visualizar la relación entre las categorías de fila y columna
# Esta versión del biplot se construye con ggplot2
# --------------------------------------------------------------------------------------
# Extraer las coordenadas de las filas (zonas)
row_coords <- as_tibble(res.ca$row$coord) %>%
mutate(label = rownames(res.ca$row$coord))
# Extraer las coordenadas de las columnas (estratos)
col_coords <- as_tibble(res.ca$col$coord) %>%
mutate(label = rownames(res.ca$col$coord))
Conclusiones del Biplot del Análisis de Correspondencia
Asociaciones Geográficas y Socioeconómicas: El análisis muestra una clara asociación entre las zonas de la ciudad y los estratos socioeconómicos. Esto significa que la distribución de los estratos no es aleatoria en toda la ciudad, sino que está geográficamente concentrada.
Relación entre Zonas y Estratos Específicos:
Zona Sur y Estrato 5/6: La Zona Sur está fuertemente asociada con los estratos 5 y 6. Sus puntos están muy cerca en el biplot y en el mismo cuadrante. Esto indica que las propiedades en la Zona Sur tienen una alta probabilidad de pertenecer a los estratos socioeconómicos más altos.
Zona Norte y Estrato 4: La Zona Norte está claramente asociada con el estrato 4. Esto sugiere que esta zona es predominantemente de clase media-alta.
Zona Oriente y Estrato 2/3: La Zona Oriente tiene una asociación fuerte con los estratos 2 y 3. Esto la posiciona como una zona de clase media-baja.
Zona Oeste y Estrato 3: La Zona Oeste está más cerca del estrato 3. Aunque la asociación es menos fuerte que en las otras zonas, sigue sugiriendo una predominancia de este estrato.
Proximidad en el Biplot: La distancia entre los puntos en el biplot es clave. Cuanto más cerca están un punto de zona y un punto de estrato, más fuerte es su asociación. Por ejemplo, la distancia entre Zona Sur y 5 y 6 es muy corta, al igual que la de Zona Oriente y 2 y 3. Las distancias mayores, como entre Zona Sur y 2, indican una baja asociación.
En resumen, los gráficos confirman que las zonas geográficas de la ciudad están directamente relacionadas con la distribución de los estratos socioeconómicos, permitiendo identificar claramente la composición social de cada una de las zonas.
# Selecciona las columnas que quieres analizar
columnas_interes <- c("zona","tipo","barrio")
# Transformar los datos para obtener conteos por categoría, el dataframe data_g es un dataframe de pruebas
data_g <- vivienda %>%
select(all_of(columnas_interes)) %>%
pivot_longer(cols = everything(), names_to = "Categoria", values_to = "Subcategoria") %>%
count(Categoria, Subcategoria)
# Crear el gráfico con ggplot2
ggplot(data_g, aes(x = Subcategoria, y = n, fill = Categoria)) +
geom_bar(stat = "identity", color = "black") +
facet_wrap(~Categoria, scales = "free_x") + # Una gráfica por cada categoría
theme_minimal() +
ggtitle("Gráfica 1. Conteo de Categorías por variables") +
xlab("Categoría") +
ylab("Conteo") +
theme(
axis.text.x = element_text(angle = 45, hjust = 1, size = 10), # Rotar etiquetas del eje X
plot.margin = margin(10, 10, 10) # Ajustar márgenes
)