1. Introducción

El mercado de bienes raíces en Cali ha crecido significativamente en los últimos años, impulsado por el crecimiento de la población, la inversión extranjera directa y el desarrollo de nuevos proyectos inmobiliarios. En 2022, las ventas del sector en Cali llegaron a $6700 millones y en 2023 a $6100 mil millones. Se espera que este sector continue creciendo durante los próximos años, permitiendo un desarrollo dinámico en la economía regional.

A continuación se presenta el análisis se basa en una combinación de datos estadísticos de la base de datos recogida por la empresa inmobiliaria B&C, en el que se encuentran características de la vivienda como Tipo de vivienda, piso, estrato, zona geográfica, habitaciones, baños, entre otras que se presentarán mediante gráficos de visualización e interpretaciones para posibles tomas de desiciones.

2. Objetivos

2.1 Objetivo General

Caracterizar las viviendas de Cali recogida por la inmobiliaria B&C.

2.2 Objetivos específicos

  1. Analizar el precio de las viviendas en diferentes zonas de Cali: se busca una interpretación detallada de la variación de precios de las viviendas en distintas zonas de Cali para identificar oportunidades de inversión, establecer estrategias de precios competitivos y definir así un alcance geográfico para futuros proyectos inmobiliarios.

  2. Identificar el tipo de viviendas más ofertadas en Cali: conocer los tipos de viviendas que predominan en el mercado inmobiliario para que la empresa pueda adaptar su oferta a las demandas del mercado, como definir su nicho de mercado de manera más precisa y por ende diseñar estrategias de marketing.

  3. Analizar las características más relevantes de la oferta de vivienda en Cali: proporcionar a análisis sobre las características de las viviendas disponibles en el mercado en aspectos como tamaño, ubicación, entre otros.

Métodos

A continuación se describen cada uno de los pasos que se desarrollaron en el análisis, desde la recopilación de la información hasta la interpretación de los resultados.

  1. Recopilación de los datos: Además del uso de la base de datos recogida y proporcionada por la empresa B&C, también se trabajó con archivos tipo .shp para análisis georreferenciado de los datos; de esta última se tuvo en cuenta analizar con la comuna, que era una variable que no se encontraba en la base de datos inicial.

  2. Limpieza y procesamiento de datos: Se realizó búsqueda de definiciones de Casa y Vivienda en Colombia, por esto, se reclasificó el tipo de vivienda tomando que toda vivienda que tuviera más de 3 pisos, sería Apartamento en vez de Casa. Se encontraron tres viviendas que no tenían ninguna información de las variables, por lo que se optó eliminarlas. La variable Piso se encontraba con más de 30% de valores faltantes que fueron imputados por la moda teniendo en cuenta las variables zona, tipo de vivienda y comuna, bajando así la proporción de datos faltantes de esta variable a menos del 1%, los cuales fueron eliminados. Por último, debido a la variabilidad de la información que se presenta en la base de datos, se tomó la desición de trabajar con los datos faltantes (30%) de la variable precio de la vivienda sin eliminarlos. En cuanto a las variables de longitud y latitud, se estandarizaron los valores y se reclasificó la zona manipulando el mapa de Cali con sus zonas geográficas. Finalmente, toda incongruncia en la variable fue reclasificada, teniendo así un total de 8316 viviendas a analizar.

  3. Análisis: Se realizaron análisis descriptivos mediante visualizaciones gráficas.

3. Resultados

3.1. Base de datos

La base de datos estudiada presenta la siguiente estructura:
# Importar datos desde Excel
df_0 = df[, c("id", "zona_alcaldia", "piso_2", "estrato", "preciom", "areaconst", "parquea", 
              "banios", "habitac", "tipo_modif", "barrio", "longitud", "latitud", "COMUNA")]

print(df_0)
## # A tibble: 8,316 × 14
##       id zona_alcaldia piso_2 estrato preciom areaconst parquea banios habitac
##    <dbl> <chr>          <dbl>   <dbl>   <dbl>     <dbl>   <dbl>  <dbl>   <dbl>
##  1     1 Zona Oriente       2       6     880     237         2      5       4
##  2     2 Zona Oriente       2       4    1200     800         3      6       7
##  3     3 Zona Oriente       3       5     250      86        NA      2       3
##  4     4 Zona Oriente       6       6    1280     346         4      6       5
##  5     5 Zona Oriente       2       6    1300     600         4      7       5
##  6     6 Zona Oriente       3       6     513     160         2      4       4
##  7     7 Zona Oriente       2       6     870     490         3      6       5
##  8     8 Zona Oriente       5       5     310      82.5       1      2       3
##  9     9 Zona Oriente       9       4     240      80         1      2       3
## 10    10 Zona Oriente       6       6     690     150         2      5       4
## # ℹ 8,306 more rows
## # ℹ 5 more variables: tipo_modif <chr>, barrio <chr>, longitud <dbl>,
## #   latitud <dbl>, COMUNA <dbl>

Además, las comunas que conforman cada zona geográfica de Cali se presenta en la siguiente tabla:

tabla <- data.frame(
  Zona = c("Zona Centro", "Zona Norte", "Zona Oeste", "Zona Oriente", "Zona Sur"),
  Comunas = c("3, 8, 9, 10, 11, 12", "2, 4, 5, 6", 
              "1, 18, 19, 20", "7, 13, 14, 15 16, 21", "17, 22")
  )

library(gt)
tabla %>%
  gt()
Zona Comunas
Zona Centro 3, 8, 9, 10, 11, 12
Zona Norte 2, 4, 5, 6
Zona Oeste 1, 18, 19, 20
Zona Oriente 7, 13, 14, 15 16, 21
Zona Sur 17, 22

3.2. Análisis de precio por tipo de vivienda

Analizando los precios de las viviendas por zona geográfica, puede evidenciarse que llegan a concentrarse en precios bajos, pero a su vez, cada una de ellas presentan viviendas con costos muy altoss. Incluso en la Zona Oriente, que a pesar de que la distribución de los precios es baja, hay viviendas con precios altos. Lo que permite analizar qué variables están relacionadas a que el precio de vivienda en cada zona sea alto o no.

De igual manera, se observa que los precios de las casas y apartamentos en las zonas Centro, Norte, Oeste y Oriente no se identifica diferencias significativas entre ellas y donde sí se tiene en la zona Sur, pues las casas llegan a tener un precio alto en comparación con los apartamentos.
library(dplyr)
library(ggplot2)
library(tidyverse)
library(hrbrthemes)
library(viridis)

df %>%
  ggplot(aes(x=factor(zona_alcaldia), y=preciom, fill=factor(tipo_modif))) +
  geom_boxplot() +
  scale_fill_viridis(discrete = TRUE, alpha=0.6) +
  geom_jitter(color="black", size=0.4, alpha=0.9) +
  theme_ipsum() +
  theme(legend.position="bottom",
    plot.title = element_text(size=11)
  ) +
  ggtitle("Precio del tipo de viviendas por zona en Cali") +
  xlab("Zona")+ ylab("Precio vivienda") + labs(fill="Tipo de vivienda")

3.3 Tipo de vivienda: Precio por área construida

Como lo visto en el gráfico anterior, el precio de las casas es un poco más alto que el de los apartamentos y eso se evidencia en el siguiente diagrama de puntos, donde también se muestra que las casas son más grandes que los apartamentos, como es de esperarse. Sin embargo, una característica que puede notarse es que discriminando el análisis por región, las áreas construidas son similares entre ellas en comparación con el precio de la vivienda. El Sur es la zona que presenta además de precio altos, viviendas con áreas más grandes, aunque sólo se vea esto último en pocos casos.
df %>%
  ggplot(aes(x=areaconst, y=preciom, color=tipo_modif)) +
  geom_point(alpha=0.7) +
  facet_grid(~zona_alcaldia) + 
  scale_colour_discrete(name  ="Tipo de vivienda") + 
  ggtitle("Precio por área construida") +
  xlab("Área construida")+ ylab("Precio vivienda") +
  theme_minimal()

3.4. Tipo de vivienda: Habitaciones por área construida

Las habitaciones por área construida, sin importar el tipo de vivienda, se ve en su mayoría las viviendas tienen entre 3 y 4 habitaciones que vienen dadas por áreas construidas menores a 500 m2. Analizando los percentiles de los boxplot, se observa que existen comportamientos inusuales en el número de habitaciones, pues hay apartamentos que tienen más habitaciones que en las casas, como ocurre con la cantidad de 7 y 9.
df %>%
  ggplot(aes(x=factor(habitac), y=areaconst, fill=factor(tipo_modif))) +
  geom_boxplot() +
  scale_fill_viridis(discrete = TRUE, alpha=0.6) +
  geom_jitter(color="black", size=0.4, alpha=0.9) +
  theme_ipsum() +
  theme(legend.position="bottom",
        plot.title = element_text(size=11)
  ) +
  ggtitle("Área construida por número de habitaciones") +
  xlab("Número de habitaciones")+ ylab("Área construida") + labs(fill="Tipo de vivienda")

3.5. Tipo, piso, estrato y precio de la vivienda

Al graficar estas variables en conjunto, se puede observar la relación que puede haber entre ellas. Se observa que la cantidad de apartamentos supera la de casas en la ciudad, como también que hay apartamentos hasta de 12 pisos. Además de que la mayor cantidad de pisos se encuentra en el estrato 5. El piso expone ser una variable que no varía mucho en su precio, cuando en el gráfico de puntos muestra tener un comportamiento similar.
library(GGally)
ggpairs(
  df[, c("tipo_modif", "piso" ,"estrato", "preciom")], 
  columnLabels=c("Tipo", "Piso", "Estrato", "Precio"),
  upper = list(continuous = "density", combo = "box_no_facet"),
  lower = list(continuous = "points", combo = "dot_no_facet")
)

3.6. Zonas y comunas

Debido a la variabilidad en los datos por zona, es necesario realizar el análisis por la mediana como se observa en la tabla, donde los precios medianos por zona y comuna se encuentran; Zona Norte-Comuna 6 ($120), Zona Oriente-Comuna 13 ($135), Zona Oeste-Comuna 18 ($200), Zona Centro-Comuna 10 ($230) y Zona Sur-Comuna 17 ($270).
est_comuna<- df %>%
  group_by(zona_alcaldia, COMUNA) %>%
  summarise(Minimo = min(preciom, na.rm = TRUE),
            Media = mean(preciom, na.rm = TRUE),
            Mediana = median(preciom, na.rm = TRUE),
            Maximo = max(preciom, na.rm = TRUE),
            Coef_Variacion = sd(preciom, na.rm = TRUE)/mean(preciom, na.rm = TRUE)) %>%
  arrange(Mediana)

print(est_comuna)
## # A tibble: 22 × 7
## # Groups:   zona_alcaldia [5]
##    zona_alcaldia COMUNA Minimo Media Mediana Maximo Coef_Variacion
##    <chr>          <dbl>  <dbl> <dbl>   <dbl>  <dbl>          <dbl>
##  1 Zona Norte         6     70  164.    120     850          0.727
##  2 Zona Oriente      13     62  187.    135     430          0.659
##  3 Zona Norte         5     65  213.    159    1650          0.940
##  4 Zona Oeste        18     78  261.    200    1800          0.891
##  5 Zona Oriente       7     58  241.    220     500          0.437
##  6 Zona Oriente      15     78  326.    226.   1650          0.987
##  7 Zona Centro       10     70  292.    230    1900          0.803
##  8 Zona Centro       12     62  301.    240    1350          0.811
##  9 Zona Norte         4     72  296.    240    1590          0.760
## 10 Zona Centro        8     87  275.    255    1200          0.571
## # ℹ 12 more rows

4. Discusión

El análisis de los precios de las viviendas por zona geográfica expuso una variedad significativa en el mercado inmobiliario de Cali. Aunque en general se observa una concentración de precios bajos, se puede decir que hay presencia de viviendas con costos considerablemente altos en todas las zonas. Este comportamiento sugiere la influencia de múltiples variables en la fijación de precios, las cuales deben ser investigadas más a fondo. Se destaca además la presencia de viviendas de precios altos incluso en la Zona Oriente, donde la distribución de precios tiende a ser más baja en comparación con otras áreas de la ciudad.

Además, al analizar la relación entre los precios de las casas y los apartamentos en diferentes zonas, se encuentra que las diferencias no son uniformes. Mientras que en las zonas Centro, Norte, Oeste y Oriente no se identifican diferencias significativas en los precios entre casas y apartamentos, en la zona Sur se observa una tendencia hacia precios más altos en las casas en comparación con los apartamentos. Esto puede tener implicaciones importantes para el desarrollo de estrategias de precios y marketing por parte de las empresas del sector inmobiliario.

Otro aspecto destacado es la relación entre el precio y el tamaño de las viviendas. En general, se encontró que el precio de las casas tiende a ser ligeramente más alto que el de los apartamentos, lo cual es coherente con lo qeu se espera de que las casas sean más grandes. Sin embargo, al analizar esta relación por región, se observa que las áreas construidas son similares entre las distintas zonas, lo que sugiere que otros factores pueden estar influyendo en la fijación de precios.

En cuanto al número de habitaciones por área construida, se encuentra un patrón donde la mayoría de las viviendas tienen entre 3 y 4 habitaciones, independientemente del tipo de vivienda. Sin embargo, también se exponen comportamientos inusuales, como apartamentos con más habitaciones que algunas casas, evidenciando una demanda por viviendas más amplias en ciertas zonas de la ciudad.

Finalmente, al analizar la relación entre el número de pisos, el estrato y el precio de las viviendas, se obtuvo que la mayoría de los apartamentos estudiados en Cali tienen menos de 12 pisos. También que el estrato 5 es el que concentra la mayor cantidad de pisos. No obstante, la variable del piso parece tener un impacto limitado en el precio de las viviendas, lo que sugiere que otros factores pueden estar ejerciendo una mayor influencia en la fijación de precios.

5. Conclusiones

El análisis del mercado inmobiliario en Cali revela una serie de hallazgos significativos que pueden orientar a estrategias y decisiones de las empresas del sector. A partir de los datos recopilados y analizados, se puede llegar a las siguientes conclusiones:

  1. Variabilidad en los precios por zona geográfica: Aunque existe una tendencia hacia precios bajos en general, se observa una variabilidad en los precios de las viviendas en diferentes zonas de la ciudad.

  2. Diferencias en los precios entre casas y apartamentos: Si bien el análisis muestra que las casas tienden a tener precios ligeramente más altos que los apartamentos, esta diferencia no es uniforme en todas las zonas. Sería fundamental comprender estas variaciones para adecuar una oferta y estrategias de precios a las demandas específicas de cada zona.

  3. Relación entre el tamaño y el precio de las viviendas: Aunque se esperaría que el precio de una vivienda esté relacionado con su tamaño, se encontró que esta relación no es siempre sigue la misma dirección.

  4. Demanda por viviendas amplias en ciertas áreas: El análisis del número de habitaciones por área construida reveló una demanda particular por viviendas más amplias en ciertas áreas de la ciudad.

  5. Impacto limitado del número de pisos en el precio de las viviendas: A pesar de que el número de pisos puede variar entre las viviendas, encontramos que esta variable tiene un impacto limitado en el precio.

Lo anterior viene soportado de los información que se encontró en la base de datos. A pesar de la realización de la limpieza de la información y de las incongruencias, hubo variables en las que no fue posible estandarizarlas debido a comportamientos inusuales, donde seguramente se deba a cómo se entendía por Casa y Apartamento.

6. Anexos

En este apartado se encuentra la limpieza y estandarización de cada una de las variables de la base de datos en estudio. Se realizará un análisis aparte de la georreferenciación de estas viviendas, lo que corregirá las zonas en las que ellas se encuentran.
library(paqueteMETODOS)
data(vivienda_faltantes)
data_viviendas <- vivienda_faltantes

6.1 Contexto

En el contexto del análisis de viviendas en la ciudad de Cali, es fundamental entender las definiciones de vivienda que permitan realizar una correcta limpieza y análisis de los tipos de propiedades; Apartamento y Casa.

Con el objetivo de obtener una comprensión sólida de estas definiciones, se llevó a cabo una una búsqueda de definiciones en la página oficial del Departamento Administrativo Nacional de Estadística (DANE)(https://www.dane.gov.co/index.php?option=com_content&view=article&id=168&itemid=117), las cuales se describen a continuación:

  1. Vivienda: Es un espacio independiente y separado, habitado o destinado para ser habitado por una o más personas. Independiente, porque tiene acceso directo desde la vía pública, caminos, senderos o a través de espacios de circulación común (corredores o pasillos, escaleras, ascensores, patios).

  2. Casa: Es la edificación constituida por una sola unidad cuyo uso es el de vivienda, con acceso directo desde la vía pública o desde el exterior de la edificación. El servicio sanitario y la cocina pueden estar o no dentro de ella. También se consideran casas aquellas en donde el garaje, la sala o alguna habitación se destinan para uso económico.

  3. Apartamento: Es una unidad de vivienda que hace parte de una edificación, en la cual hay otra(s) unidad(es) que generalmente es (son) de vivienda. Tiene acceso directo desde el exterior o por pasillos, patios, corredores, escaleras o ascensores. Dispone de servicio sanitario y cocina en su interior. Por ejemplo, los bloques multifamiliares generalmente están constituidos por apartamentos; una casa que se reforma para construir varias unidades de vivienda con sanitario y cocina para cada nueva unidad, se convierte en varios apartamentos.

6.2 Limpieza de los datos

Se realizó el análisis descriptivo de cada una de las variables de manera preliminar para encontrar posibles incongruencias o datos faltantes. Analizando cada una de ellas se tiene lo siguiente:

6.2.1. Zona

Se observa que la variable contiene tiene 3 valores faltantes. Dado a que esta cantidad de NA´s es menor al 1%, se considera eliminar estas viviendas.
summarytools::freq(data_viviendas$zona, cumul = F)
## Frequencies  
## data_viviendas$zona  
## Type: Character  
## 
##                      Freq   % Valid   % Total
## ------------------ ------ --------- ---------
##        Zona Centro    124     1.489     1.489
##         Zona Norte   1922    23.082    23.073
##         Zona Oeste   1204    14.459    14.454
##       Zona Oriente    351     4.215     4.214
##           Zona Sur   4726    56.755    56.735
##               <NA>      3               0.036
##              Total   8330   100.000   100.000

6.2.2. Piso

En este caso, la variable tiene más del 30% de valores faltantes, por lo que eliminarlos no sería buena opción. Dada la naturaleza de la variable; cualitativa-ordinal y donde se tienen muchas categorías en las que una imputación por modelo logístico sobre estimaría los valores, se considera realizar imputación por la moda, teniendo en cuenta variables como zona, tipo y comuna.
summarytools::freq(data_viviendas$piso, cumul = F)
## Frequencies  
## data_viviendas$piso  
## Type: Numeric  
## 
##               Freq   % Valid   % Total
## ----------- ------ --------- ---------
##           1    861     15.13     10.34
##           2   1450     25.49     17.41
##           3   1097     19.28     13.17
##           4    607     10.67      7.29
##           5    568      9.98      6.82
##           6    245      4.31      2.94
##           7    207      3.64      2.48
##           8    211      3.71      2.53
##           9    146      2.57      1.75
##          10    130      2.29      1.56
##          11     84      1.48      1.01
##          12     83      1.46      1.00
##        <NA>   2641               31.70
##       Total   8330    100.00    100.00

6.2.3. Estrato

En esta variable, se encuentran 3 valores faltantes, que dado a ser muy pequeña esta cantidad, se considera eliminar estas viviendas.
summarytools::freq(data_viviendas$estrato, cumul = F)
## Frequencies  
## data_viviendas$estrato  
## Type: Numeric  
## 
##               Freq   % Valid   % Total
## ----------- ------ --------- ---------
##           3   1453    17.449    17.443
##           4   2131    25.591    25.582
##           5   2751    33.037    33.025
##           6   1992    23.922    23.914
##        <NA>      3               0.036
##       Total   8330   100.000   100.000

6.2.4. Barrio

Debido a que los barrios se presentan con caracteres especiales como puntos (.), comas (;) y tíldes (´) se necesita realizar la estandarización de éstas, pues muchos barrios, a pesar de ser los mismos, difieren de estos caracteres.
data_viviendas[,"barrio"]
Luego, aplicando la limpieza de los barrios, se tendría esta variable de la siguiente manera:
library(stringdist) #función creada por la profesora J.P.

limpiar_barrios <- function(nombres) {
  nombres <- tolower(trimws(iconv(nombres, from = "UTF-8", to = "ASCII//TRANSLIT")))
  nombres <- gsub("[_ ]", "", nombres)
  return(nombres)
}
data_viviendas$barrio2 <- limpiar_barrios(data_viviendas$barrio)

#print(data_viviendas$barrio2)

6.2.5. Tipo

Como se observa, hay dos tipos de zona; Apartamento y Casa, sin embargo hay categorías que escritas de otra manera pareciera ser una categoría más. Por esto es necesario estandarizar las categorías de la variables.
summarytools::freq(data_viviendas$tipo, cumul = F)
## Frequencies  
## data_viviendas$tipo  
## Type: Character  
## 
##                     Freq   % Valid   % Total
## ----------------- ------ --------- ---------
##       Apartamento   5032    60.430    60.408
##       APARTAMENTO     61     0.733     0.732
##              apto     13     0.156     0.156
##              casa     14     0.168     0.168
##              Casa   3195    38.369    38.355
##              CASA     12     0.144     0.144
##              <NA>      3               0.036
##             Total   8330   100.000   100.000
Luego, estandarizadas, se tiene el siguiente comportamiento de las frecuencias de la variable:
library(dplyr)
attach(data_viviendas)
data_viviendas$tipo[which(tipo=="APARTAMENTO" | tipo=="apto")] <- "Apartamento" 
data_viviendas$tipo[which(tipo=="CASA" | tipo=="casa")] <- "Casa"
data_viviendas %>% group_by(tipo) %>% count(tipo)
De igual manera, se encontraron casas con más de 3 pisos, por lo que se corregirá esta variable poniendo de condición que si la vivienda es de tipo Casa y la cantidad de pisos es mayor que 3, entonces se clasifique como Apartamento, siguiendo así las definiciones del DANE.
data_viviendas$tipo_modif <- data_viviendas$tipo
casas_p4 <- data_viviendas %>% filter(tipo=="Casa", piso>3)
data_viviendas$tipo_modif[which(tipo=="Casa" & piso>3)] <- "Apartamento" 
data_viviendas$tipo_modif[which(id==793)] <- "Apartamento" 

table(data_viviendas$piso, data_viviendas$tipo_modif)
##     
##      Apartamento Casa
##   1          431  430
##   2          512  938
##   3          573  524
##   4          607    0
##   5          568    0
##   6          245    0
##   7          207    0
##   8          211    0
##   9          146    0
##   10         130    0
##   11          84    0
##   12          83    0

6.2.6. Precio

Se encuentran 3 valores faltantes que pueden considerarse como eliminados de la base de datos. Se observa además, que el rango de valores parece no tener incongruencias.
summary(data_viviendas$preciom)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##    58.0   220.0   330.0   434.2   540.0  1999.0       2

6.2.7. Área construida

A pesar que se encuentra que hay una vivienda de 30 m2 que tiene 3 habitaciones y 2 baños u otros casos con áreas muy grandes, se toma la desición que en vez de corregir estos valores, se tenga precaución al realizar los análisis no usando estadísticas sensibles a valores atípicos como la media.
summary(data_viviendas$areaconst)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##      30      80     123     175     229    1745       3

6.2.8. Parqueaderos

La variable tiene gran cantidad de valores faltantes. Se revisó realizando tablas de contingencia junto con las otras variables y no se encontró alguna relación entre ellas. Además de que un sólo apartamento no se esperaría tener más de 5 parqueaderos, por lo que se opta por dejar esta variable con los NA´S sin imputar.
summary(data_viviendas$parquea)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##   1.000   1.000   2.000   1.836   2.000  10.000    1606

6.2.9. Baños

Se encuentran viviendas con 0 baños, siendo menos del 1% de las viviendas estudiadas. Se encontró que las viviendas que no tiene baños, tampoco tienen habitaciones, por lo que se pudiera pensar que se trata de establecimientos comerciales o lotes sin edificaciones.
summarytools::freq(data_viviendas$banios, cumul = F)
## Frequencies  
## data_viviendas$banios  
## Type: Numeric  
## 
##               Freq   % Valid   % Total
## ----------- ------ --------- ---------
##           0     45     0.540     0.540
##           1    497     5.969     5.966
##           2   2946    35.379    35.366
##           3   1994    23.946    23.938
##           4   1460    17.533    17.527
##           5    891    10.700    10.696
##           6    315     3.783     3.782
##           7    107     1.285     1.285
##           8     48     0.576     0.576
##           9     15     0.180     0.180
##          10      9     0.108     0.108
##        <NA>      3               0.036
##       Total   8330   100.000   100.000

6.2.10. Habitaciones

Como se observó en la variable de los baños, esta variable tiene relación a que sin habitaciones tampoco hay baños. Por esto, se pensaría que se tratasen de lotes o establecimientos comerciales.
summarytools::freq(data_viviendas$habitac, cumul = F)
## Frequencies  
## data_viviendas$habitac  
## Type: Numeric  
## 
##               Freq   % Valid   % Total
## ----------- ------ --------- ---------
##           0     66     0.793     0.792
##           1     59     0.709     0.708
##           2    927    11.132    11.128
##           3   4101    49.249    49.232
##           4   1731    20.788    20.780
##           5    680     8.166     8.163
##           6    318     3.819     3.818
##           7    173     2.078     2.077
##           8    138     1.657     1.657
##           9     83     0.997     0.996
##          10     51     0.612     0.612
##        <NA>      3               0.036
##       Total   8330   100.000   100.000

6.2.11. Longitud y latitud

Primero, se identifica que las variables de longitud y latitud no se encuentran estandarizadas, por lo que es necesario realizar este paso en el pre-procesamiento de la información.
summary(data_viviendas$longitud)
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max.      NA's 
## -76576.00 -76506.00    -76.54 -21845.13    -76.52    -76.46         3
summary(data_viviendas$latitud)
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max.     NA's 
##    3.333    3.390    3.450  970.370 3367.000 3497.000        3
Estandarizando los datos de estas dos variables se tiene lo siguiente:
data_viviendas <- data_viviendas %>%
  mutate(longitud = ifelse(!grepl("\\.", as.character(longitud)), longitud/1000, longitud))
data_viviendas <- data_viviendas %>%
  mutate(latitud = ifelse(!grepl("\\.", as.character(latitud)), latitud/1000, latitud))

coordenadas = cbind(data_viviendas$longitud, data_viviendas$latitud, data_viviendas$barrio2, data_viviendas$zona)
colnames(coordenadas) = c("longitud", "latitud", "barrio2", "zona")
coordenadas <- data.frame(coordenadas)

summary(data_viviendas$longitud)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##  -76.59  -76.54  -76.53  -76.53  -76.52  -76.46       3
summary(data_viviendas$latitud)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##   3.333   3.381   3.416   3.418   3.452   3.498       3
Sólo con los datos que se tienen en la base de datos, se grafica el mapa para evaluar la distribución de las viviendas en Cali, que sin discriminar el mapa por zonas, se puede observar que se combinan los puntos de las viviendas en muchas zonas, por lo que se hace necesario estandarizar las ubicaciones de las viviendas.
library(ggplot2)
ggplot(data_viviendas, aes(longitud, latitud, colour=factor(zona))) + 
  geom_point() +
  labs(title="Distribución de los barrios en Cali por zona") +
  scale_colour_discrete(name  ="Zona") +
  theme_minimal()

Se decide corregir estas dos variables debido a que, al pertenecer viviendas en una zona que no corresponden, puede dar un análisis no cercano a lo que es en realidad, tales como precios, áreas construidas o barrios. Por tanto, se hará análisis georreferenciado con manipulación de archivos shapefile del mapa de Cali.

Por lo anterior, se buscó en la página de la Alcaldía de Cali cómo se distribuía las zonas geográficas en la ciudad de Cali (https://www.cali.gov.co/planeacion/publicaciones/169423/zonas_geograficas_idesc/). Luego, se descargó el archivo shapefile del mapa de las comunas de Cali y tomando como base el mapa de las zonas geográficas, se agruparon las comunas que pertenecían a cada una de ellas. Finalmente se grafica para corroborar si efectivamente las viviendas no coinciden con las zonas geográficas.
datos_excel <- datos_excel %>% filter(is.na(longitud)==FALSE, is.na(latitud)==FALSE)
datos_excel$longitud <- as.numeric(datos_excel$longitud)
datos_excel$latitud <- as.numeric(datos_excel$latitud)

library(sp)
# Crear un objeto con las coordenadas SpatialPointsDataFrame
coordinates(datos_excel) <- c("longitud", "latitud")
proj4string(datos_excel) <- CRS("+proj=longlat +datum=WGS84")  #se define la proyección

# Crear un objeto sf
library(sf)
sf_objeto <- st_as_sf(datos_excel)
mapa_cali$zona_alcaldia <- c()

# Asignar zonas según las comunas
mapa_cali$zona_alcaldia[mapa_cali$NOMBRE %in% c("Comuna 2", "Comuna 4", "Comuna 5", "Comuna 6")] <- "Zona Norte"
mapa_cali$zona_alcaldia[mapa_cali$NOMBRE %in% c("Comuna 7", "Comuna 13", "Comuna 14", 
                                                "Comuna 15", "Comuna 16","Comuna 21")] <- "Zona Oriente"
mapa_cali$zona_alcaldia[mapa_cali$NOMBRE %in% c("Comuna 22", "Comuna 17")] <- "Zona Sur"
mapa_cali$zona_alcaldia[mapa_cali$NOMBRE %in% c("Comuna 18", "Comuna 19", "Comuna 20", 
                                                "Comuna 1")] <- "Zona Oeste"
mapa_cali$zona_alcaldia[mapa_cali$NOMBRE %in% c("Comuna 3", "Comuna 9", "Comuna 10", 
                                                "Comuna 11", "Comuna 12", "Comuna 8")] <- "Zona Centro"

ggplot() +
  geom_sf(data = mapa_cali, aes(fill = zona_alcaldia)) +
  geom_sf(data = sf_objeto, aes(color = zona)) +
  scale_color_manual(values = c("blue", "red", "green", "orange", "purple")) +
  scale_fill_manual(values = c("blue", "red", "green", "orange", "purple")) +
  ggtitle("Distribución de viviendas por zona") +
  guides(fill=guide_legend(title="Zona")) +
  theme(plot.title = element_text(hjust = 0.5)) +
  theme_minimal() 

Finalmente se realiza intersección entre el mapa y las viviendas, así cada vivienda que se encuentre en respectiva zona del mapa, quedará catalogado como esa región en la que está y no como se describe en la base de datos.
library(sf)
sf_objeto <- st_transform(sf_objeto, st_crs(mapa_cali))
out <- st_intersection(sf_objeto, mapa_cali)

ggplot() +
  geom_sf(data = mapa_cali, aes(fill = zona_alcaldia)) +
  geom_sf(data = out, aes(color = zona_alcaldia)) +
  scale_color_manual(values = c("blue", "red", "green", "orange", "purple")) +
  scale_fill_manual(values = c("blue", "red", "green", "orange", "purple")) +
  ggtitle("Distribución de viviendas por zona ajustado") +
  guides(fill=guide_legend(title="Zona")) +
  theme(plot.title = element_text(hjust = 0.5)) +
  theme_minimal() 

7. Base de datos final

Realizando la eliminación de las viviendas con valores faltantes; zona, estrato, precio, areacost, banios, habitac, tipo y latitud y longitud, finalmente se cuentan con 8316 viviendas a analizar.
na <- which(is.na(data_viviendas$zona))
data_viviendas_sinNA <- data_viviendas[-na, ]
#nrow(data_viviendas_sinNA)          
data_viviendas_sinNA = arrange(data_viviendas_sinNA, id)
mode <- function(x, na.rm = FALSE) {
  if (na.rm) {
    x <- x[!is.na(x)]
  }
  ux <- unique(x)
  ux[which.max(tabulate(match(x, ux)))]
}

data_v = data_v %>%
  group_by(COMUNA, estrato, tipo_modif) %>%
  mutate(piso_2 = ifelse(is.na(piso), 
                       mode(piso, na.rm = TRUE), # Calcula la moda de 'piso' para cada grupo
                       piso)) %>%
  ungroup()

#se eliminan los 11 valores faltantes que tiene la variable piso
na_2 <- which(is.na(data_v$piso_2))
data_v <- data_v[-na_2, ]
nrow(data_v)  
## [1] 8316