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. La empresa B&C ha recogido información sobre viviendas que incluye información sobre el precio, la ubicación, las características y la venta de viviendas en Cali.

A continuación, se tomara esta base datos para la realización de un análisis estadístico descriptivo el cual nos permita tener un panorama del mercado inmobiliario en la ciudad de Cali.

2 Objetivos

3 Métodos

Se tomó como insumo la base de datos denominada “vivienda_faltantes” provista por la inmobiliaria y se procedió a una identificación de las variables que esta poseía, una limpieza de datos, eliminando registros que se encontraban vacíos, estandarizando resultados de variables e imputando los valores faltantes. Para el análisis estadístico, inicialmente se realizó un análisis univariado. Las variables cuantitativas se analizaron con medidas de tendencia central o de dispersión y para las variables cualitativas se analizaron con tablas de frecuencias y gráficos de torta o de barras los cuales según la literatura son los más apropiadas para cada tipo de variables. También se procedió a realizar cruces entre variables para identificar patrones por tipo de vivienda y zonas. Todo esto bajo las siguientes librerías de R que se mencionan a continuación:

library(paqueteMETODOS)
library(readr)
library(summarytools)
library(dplyr)
library(mice)

4 Resultados

Inicialmente se realizó la limpieza de los datos, eliminando registros vacíos y realizando imputación de datos según el comportamiento de las variables para posteriormente realizar los análisis estadísticos descriptivos correspondientes.

4.1 Limpieza

La revisión inicial de la base de datos arrojo los siguientes resultados:

head(vivienda_faltantes)
## # A tibble: 6 × 13
##      id zona        piso estrato preciom areaconst parquea banios habitac tipo  
##   <dbl> <chr>      <dbl>   <dbl>   <dbl>     <dbl>   <dbl>  <dbl>   <dbl> <chr> 
## 1  8312 Zona Oeste     4       6    1300       318       2      4       2 Apart…
## 2  8311 Zona Oeste     1       6     480       300       1      4       4 Casa  
## 3  8307 Zona Oeste    NA       5    1200       800       4      7       5 Casa  
## 4  8296 Zona Sur       2       3     220       150       1      2       4 Casa  
## 5  8297 Zona Oeste    NA       5     330       112       2      4       3 Casa  
## 6  8298 Zona Sur      NA       5    1350       390       8     10      10 Casa  
## # ℹ 3 more variables: barrio <chr>, longitud <dbl>, latitud <dbl>
str(vivienda_faltantes)
## spc_tbl_ [8,330 × 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ id       : num [1:8330] 8312 8311 8307 8296 8297 ...
##  $ zona     : chr [1:8330] "Zona Oeste" "Zona Oeste" "Zona Oeste" "Zona Sur" ...
##  $ piso     : num [1:8330] 4 1 NA 2 NA NA 2 NA NA 2 ...
##  $ estrato  : num [1:8330] 6 6 5 3 5 5 6 5 5 5 ...
##  $ preciom  : num [1:8330] 1300 480 1200 220 330 1350 305 480 275 285 ...
##  $ areaconst: num [1:8330] 318 300 800 150 112 390 125 280 74 120 ...
##  $ parquea  : num [1:8330] 2 1 4 1 2 8 2 4 1 2 ...
##  $ banios   : num [1:8330] 4 4 7 2 4 10 3 4 2 4 ...
##  $ habitac  : num [1:8330] 2 4 5 4 3 10 3 4 3 3 ...
##  $ tipo     : chr [1:8330] "Apartamento" "Casa" "Casa" "Casa" ...
##  $ barrio   : chr [1:8330] "arboleda" "normandía" "miraflores" "el guabal" ...
##  $ longitud : num [1:8330] -76576 -76571 -76568 -76565 -76565 ...
##  $ latitud  : num [1:8330] 3454 3454 3455 3417 3408 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   id = col_double(),
##   ..   zona = col_character(),
##   ..   piso = col_double(),
##   ..   estrato = col_double(),
##   ..   preciom = col_double(),
##   ..   areaconst = col_double(),
##   ..   parquea = col_double(),
##   ..   banios = col_double(),
##   ..   habitac = col_double(),
##   ..   tipo = col_character(),
##   ..   barrio = col_character(),
##   ..   longitud = col_double(),
##   ..   latitud = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>

La base de datos contiene 8330 registros, 13 variables tanto cualitativas como cuantitativas.

Variables cuantitativas:

id, piso, estrato, precio, área construida, numero de parqueaderos, número de baños, numero habitaciones, longitud y latitud.

Variables cualitativas: Son nominales y se encuentra la zona, el tipo de vivienda y el barrio

vivienda_faltantes[which(is.na(vivienda_faltantes$id)),]
## # A tibble: 3 × 13
##      id zona   piso estrato preciom areaconst parquea banios habitac tipo 
##   <dbl> <chr> <dbl>   <dbl>   <dbl>     <dbl>   <dbl>  <dbl>   <dbl> <chr>
## 1    NA <NA>     NA      NA      NA        NA      NA     NA      NA <NA> 
## 2    NA <NA>     NA      NA      NA        NA      NA     NA      NA <NA> 
## 3    NA <NA>     NA      NA     330        NA      NA     NA      NA <NA> 
## # ℹ 3 more variables: barrio <chr>, longitud <dbl>, latitud <dbl>

Se encontraron que hay tres registros sin datos, por lo tanto se procede a eliminarlos bajo el supuesto de que se tratan de errores, estos registros no contienen información alguna de las variables.

vivienda_faltantes <- vivienda_faltantes[!is.na(vivienda_faltantes$id),] 
g <- md.pattern(vivienda_faltantes, rotate.names = TRUE)

Se logra observar a partir del grafico anterior generado, que hay 4812 registros que tienen todos los valores de sus variables completas, 1912 tienen valores faltantes en la variable piso, 887 tienen valores faltantes en la variable parqueadero y finalmente que 726 tienen valores faltantes tanto en las variables piso como parqueadero.

Adicionalmente se observa que hay datos en algunas variables en letras mayúsculas y minúsculas por lo cual se procede a estandarizar las variables zona, tipo de vivienda en letras mayúsculas y finalmente también los valores de la variable tipo de vivienda:

vivienda_faltantes$tipo <- toupper(vivienda_faltantes$tipo)
vivienda_faltantes$zona <- toupper(vivienda_faltantes$zona)
vivienda_faltantes$tipo <- ifelse(vivienda_faltantes$tipo=='CASA','CASA','APARTAMENTO')

Para intervenir los valores faltantes de la variable piso y parqueadero, se realiza un análisis exploratorio de las variables para lograr identificar con que valor se puede proceder a imputar cada una:

hist(vivienda_faltantes$piso,
     main = "Histograma de piso",
     xlab = "Piso",
     ylab = "Frecuencia",
     col = "royalblue")

summary(vivienda_faltantes$piso)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##   1.000   2.000   3.000   3.772   5.000  12.000    2638
hist(vivienda_faltantes$parquea,
     main = "Histograma de parqueadero",
     xlab = "Parqueadero",
     ylab = "Frecuencia",
     col = "royalblue")

summary(vivienda_faltantes$parquea)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##   1.000   1.000   2.000   1.836   2.000  10.000    1603

Existen múltiples métodos para la imputación de datos faltantes, para este ejercicio y para efectos prácticos se optará por hacer uso de alguna de las medidas de tendencia central para la imputación del dato. Observamos a partir de los gráficos anteriores que los datos son asimétricos hacia la derecha para ambas variables, por lo cual no se utilizara la media, sino que se imputara los valores faltantes por medio de la mediana teniendo en cuenta que esta nos indica el punto medio de los datos y no se deja llevar por los valores atípicos.

vivienda_faltantes$piso[is.na(vivienda_faltantes$piso)] <- 3
vivienda_faltantes$parquea[is.na(vivienda_faltantes$parquea)] <- 2

4.2 Análisis univariado

4.2.1 Variables cuantitativas

En secciones anteriores ya identificamos los datos contenidos en las variables de piso y parqueadero, ahora se hara la revisión de la variable estrato:

summarytools::freq(vivienda_faltantes$estrato, cumul = T)
## Frequencies  
## vivienda_faltantes$estrato  
## Type: Numeric  
## 
##               Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
## ----------- ------ --------- -------------- --------- --------------
##           3   1453     17.45          17.45     17.45          17.45
##           4   2131     25.59          43.04     25.59          43.04
##           5   2751     33.04          76.08     33.04          76.08
##           6   1992     23.92         100.00     23.92         100.00
##        <NA>      0                               0.00         100.00
##       Total   8327    100.00         100.00    100.00         100.00

Se logra observar a partir de la tabla anterior que el estrato con mayor frecuencia es el estrato 5 con 33.04% de viviendas y en menor proporción se encuentra el estrato 3 con 17.45%. La mayor proporción de viviendas se encuentran en estratos altos con un 56.96%.

Para el area construida se tiene:

summary(vivienda_faltantes$areaconst)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##      30      80     123     175     229    1745
hist(vivienda_faltantes$areaconst,
     main = "Histograma de Área Construida",
     xlab = "Area",
     ylab = "Frecuencia",
      col= "royalblue")

Se puede observar que los datos de área construida también son asimétricos hacia la derecha y que son más frecuentes las viviendas con una menor área. A manera genera 60.07% de las viviendas tienen un área construida menor o igual de 153 metros.

## Frequencies  
## 
##               Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
## ----------- ------ --------- -------------- --------- --------------
##           0     45      0.54           0.54      0.54           0.54
##           1    497      5.97           6.51      5.97           6.51
##           2   2946     35.38          41.89     35.38          41.89
##           3   1994     23.95          65.83     23.95          65.83
##           4   1460     17.53          83.37     17.53          83.37
##           5    891     10.70          94.07     10.70          94.07
##           6    315      3.78          97.85      3.78          97.85
##           7    107      1.28          99.14      1.28          99.14
##           8     48      0.58          99.71      0.58          99.71
##           9     15      0.18          99.89      0.18          99.89
##          10      9      0.11         100.00      0.11         100.00
##        <NA>      0                               0.00         100.00
##       Total   8327    100.00         100.00    100.00         100.00

A primera vista se observa a partir de la tabla que existen 45 viviendas con 0 baños, lo cual podría tratarse de un error de digitación, no obstante se puede tratar de viviendas donde se haga un uso de baños compartidos para múltiples hogares lo que reflejaría este valor en los datos. Desde el diagrama de caja se observa datos atipicos correspondiente a tres valores con más de 8 baños por vivienda. El 50% de las viviendas tienen 3 baños o menos.

Para el area número de habitaciones se tiene:

summary(vivienda_faltantes$habitac)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   3.000   3.000   3.605   4.000  10.000
boxplot(vivienda_faltantes$habitac,horizontal = T,col = "royalblue", ylab="Habitaciones",xlab="Número de habitaciones por vivienda",main="Diagrama de caja - habitaciones")

Las viviendas en promedio cuentan con 3 habitaciones, 10 habitaciones fue el número máximo en una vivienda. Existen viviendas que no poseen habitaciones, estas serían aquellas denominadas como de un solo ambiente. Se observa a partir del grafico que los valores extremos son las viviendas con menos de 2 habitaciones y más de 6 habitaciones y que el 75% de las viviendas tienen menos de 4 habitaciones.

Por ultimo tenemos el precio de la vivienda:

hist(vivienda_faltantes$preciom,
     main = "Histograma de precio",
     xlab = "Precio",
     ylab = "Frecuencia",
     col = "royalblue")

summary(vivienda_faltantes$preciom)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    58.0   220.0   330.0   434.3   540.0  1999.0
sd(vivienda_faltantes$preciom)
## [1] 329.0335

El 25% de las viviendas cuestan menos de 220 millones de pesos y el 75% cuestan menos de 540 millones de pesos. La media fue de 434 millones de pesos con una desviación estándar de 329 millones de pesos. La vivienda con menor valor cuesta 58 millones de pesos, la que presenta mayor valor 1.999 millones de pesos.El histograma por otra parte muestra que hay menor cantidad de viviendas con precios altos, la mediana que nos indica el 50% de las viviendas tiene un precio menor a 330 millones.

4.2.2 Variables cualitativas

Respecto a las zonas, se puede observar la distibución de los datos en la siguiente gráfica y tabla:

pie(table(vivienda_faltantes$zona),
    main = "Zonas de la ciudad")

summarytools::freq(vivienda_faltantes$zona, cumul = T)
## Frequencies  
## vivienda_faltantes$zona  
## Type: Character  
## 
##                      Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
## ------------------ ------ --------- -------------- --------- --------------
##        ZONA CENTRO    124      1.49           1.49      1.49           1.49
##         ZONA NORTE   1922     23.08          24.57     23.08          24.57
##         ZONA OESTE   1204     14.46          39.03     14.46          39.03
##       ZONA ORIENTE    351      4.22          43.24      4.22          43.24
##           ZONA SUR   4726     56.76         100.00     56.76         100.00
##               <NA>      0                               0.00         100.00
##              Total   8327    100.00         100.00    100.00         100.00

La zona con mayor cantidad de viviendas es la zona sur con una frecuencia de 56.76% de las viviendas y la zona centro se encuentra la menor proporción con 1.49%.

Para el tipo de vivienda, se dividen en casa y apartamento así:

barplot(table(vivienda_faltantes$tipo), col = c("royalblue","lightblue1"),main= "Número de apartamentos y casas")

prop.table(table(factor(vivienda_faltantes$tipo)))*100
## 
## APARTAMENTO        CASA 
##     61.3186     38.6814

El 61.31% de las viviendas corresponde a apartamentos.

Si deseamos ver tipo de vivienda por zona, encontramos:

barplot(table(vivienda_faltantes$tipo,vivienda_faltantes$zona), col = c("royalblue","lightblue1"),legend.text = TRUE, main= "Tipo de vivienda por zona")

table(vivienda_faltantes$tipo,vivienda_faltantes$zona)
##              
##               ZONA CENTRO ZONA NORTE ZONA OESTE ZONA ORIENTE ZONA SUR
##   APARTAMENTO          24       1199       1035           62     2786
##   CASA                100        723        169          289     1940

Observando la gráfica y la tabla, encontramos que tanto en la zona sur, norte y oeste, la mayor frecuencia de viviendas corresponden a apartamentos y en la zona centro y oriente a casas.

4.3 Cruce de variables

table(vivienda_faltantes$estrato,vivienda_faltantes$zona)
##    
##     ZONA CENTRO ZONA NORTE ZONA OESTE ZONA ORIENTE ZONA SUR
##   3         105        572         54          340      382
##   4          14        408         85            8     1616
##   5           4        770        290            2     1685
##   6           1        172        775            1     1043

Con base en la distribución de los estratos en las diferentes zonas de la ciudad Cali, se observa en la tabla anterior que en la zona norte incluye la mayor cantidad de viviendas de estrato bajo y en la zona sur la mayor cantidad de viviendas de estrato alto.

4.3.1 Precio por area construida

plot(vivienda_faltantes$areaconst, vivienda_faltantes$preciom, col = "royalblue", 
     pch = 16,
     xlab = "Área construida en metros cuadrados",
     ylab = "Precio en millones de pesos",
     main = "Gráfica de area vs precio")
abline(lm(vivienda_faltantes$preciom~vivienda_faltantes$areaconst),col="red")

En el gráfico de dispersión se observan los precios por área construida, a manera general es claro que a mayor área construida, mayor será el precio de la vivienda y que a menor área construida, menor será el precio de la vivienda.

4.3.2 Resultados tipo de vivienda: Casa

bd_casa <- vivienda_faltantes[vivienda_faltantes$tipo == "CASA",]
summary(bd_casa$parquea)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.000   1.000   2.000   2.224   2.000  10.000
summary (bd_casa$banios)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   3.000   4.000   3.894   5.000  10.000
summary(bd_casa$habitac)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   3.000   4.000   4.609   5.000  10.000
summary(bd_casa$preciom)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    77.0   300.0   430.0   539.9   670.0  1999.0
aggregate(bd_casa$preciom, list(bd_casa$zona), FUN=mean)
##        Group.1        x
## 1  ZONA CENTRO 339.2400
## 2   ZONA NORTE 446.0913
## 3   ZONA OESTE 736.3550
## 4 ZONA ORIENTE 244.8201
## 5     ZONA SUR 612.0077

A partir de los datos anteriores generados se observa que, el 50% de las casas tienen entre 1 y 2 parqueaderos. Para los baños y habitaciones se tiene que para cada uno hay entre 3 y 5 baños y habitaciones respectivamente. Se tiene que el precio de las casas está alrededor de los 430 millones de pesos, distribuidos por zonas, se identifica que el mayor precio medio se encuentra en la zona oeste 736 millones de pesos y el menor precio medio se encuentra en la zona oriente 244 millones de pesos.

plot(bd_casa$areaconst,bd_casa$preciom , col = "royalblue", 
     pch = 16,
     xlab = "Área construida en metros cuadrados",
     ylab = "Precio en millones de pesos",
     main = "Gráfica de area vs precio")
abline(lm(bd_casa$preciom~bd_casa$areaconst),col="red")

A mayor área construída en la casa, mayor sera el precio de esta, el menor precio fue de 77 millones de pesos y el máximo de 1999 millones de pesos.

4.3.3 Resultados tipo de vivienda: Apartamento

Como se logro observar anteriormente, la mayor frecuencia de viviendas corresponde a apartamentos y se cuenta con mayor cantidad en las zonas sur y norte.

bd_apartamento <- vivienda_faltantes[vivienda_faltantes$tipo == "APARTAMENTO",]
summary(bd_apartamento$parquea)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.000   1.000   2.000   1.643   2.000  10.000
summary(bd_apartamento$banios)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   2.000   2.000   2.619   3.000   8.000
summary(bd_apartamento$habitac)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   3.000   3.000   2.972   3.000   9.000
hist(bd_apartamento$habitac,
     main = "Histograma de habitaciones",
     xlab = "Habitaciones",
     ylab = "Frecuencia",
    col = "royalblue")

summary(bd_apartamento$preciom)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    58.0   175.0   280.0   367.6   430.0  1950.0
aggregate(bd_apartamento$preciom, list(bd_apartamento$zona), FUN=mean)
##        Group.1        x
## 1  ZONA CENTRO 186.5833
## 2   ZONA NORTE 285.2577
## 3   ZONA OESTE 669.2676
## 4 ZONA ORIENTE 152.5968
## 5     ZONA SUR 297.3550

A partir de los datos anteriores generados se observa que, hay apartamentos disponibles con 1 y hasta con 10 parqueaderos, que el 50% de los apartamentos cuenta con 1 o 2 parqueaderos por vivienda y que solo el 25% cuenta con 1. Para los baños el 50% de ellos cuentan con 2 baños y tambien existen apartamentos sin baño propio. Para las habitaciones se tiene que el 75% de los apartamentos tiene menos de 3 habitaciones con un promedio de 3 y que el apartamento con mas habitaciones es de 9. Se tiene que el precio de los apartamentos está alrededor de los 367 millones de pesos, distribuidos por zonas, se identifica que el mayor precio medio se encuentra en la zona oeste 669 millones de pesos y el menor precio medio se encuentra en la zona oriente 152 millones de pesos.

plot(bd_apartamento$areaconst,bd_apartamento$preciom , col = "royalblue", 
     pch = 16,
     xlab = "Área construida en metros cuadrados",
     ylab = "Precio en millones de pesos",
     main = "Gráfica de area vs precio")
abline(lm(bd_apartamento$preciom~bd_apartamento$areaconst),col="red")

A mayor área construída en el apartamento, mayor sera el precio de este, el menor precio fue de 58 millones de pesos y el máximo de 1950 millones de pesos.

5 Discusión

6 Conclusiones