**ANALISIS MERCADO INMOBILIRIO CALI**
**B&C**
Introducción
El mercado inmobiliario de las principales ciudades del país ha presentado un crecimiento constante los últimos años, sin embargo, la pandemia de 2020 genero una crisis en el sector, una vez superadas las restricciones el dinamismo del sector continuo y se espera que los próximos años continue creciendo y siendo un motor de la economía.
Este estudio se centra en el mercado de la ciudad de Cali donde la empresa B&C tiene su centro de operación, el crecimiento del mercado inmobiliario en Cali se ha visto impulsado por el aumento de la población, la inversión extranjera directa y el desarrollo de nuevos proyectos inmobiliarios, permitiendo un desarrollo dinámico en la economía regional.
Objetivo
El objetivo de este informe es proporcionar a la empresa B&C información del mercado inmobiliario de la ciudad de Cali para definir el segmento de mercado con mayor dinamismo, asi como brindar información clave para focalizar las estrategias para llegar al mercado objetivo, las tendencias en cuanto a precios y definir la estrategia de la empresa.
Métodos
Mediante una muestra de inmuebles de la ciudad de Cali que posee la empresa B&C se realizó el análisis.
La muestra cuenta con 8330 registros con 13 variables diferentes, en primer lugar se procedió con el conocimiento de los datos y la posterior limpieza de la información disponible para hacer los respectivos análisis.
library(paqueteMETODOS)
## Loading required package: cubature
## Loading required package: dplyr
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
## Loading required package: flextable
## Loading required package: ggplot2
## Loading required package: lmtest
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
## Loading required package: MASS
##
## Attaching package: 'MASS'
## The following object is masked from 'package:dplyr':
##
## select
## Loading required package: psych
##
## Attaching package: 'psych'
## The following objects are masked from 'package:ggplot2':
##
## %+%, alpha
## Loading required package: summarytools
## Loading required package: randtests
## Loading required package: rapportools
##
## Attaching package: 'rapportools'
## The following objects are masked from 'package:summarytools':
##
## label, label<-
## The following object is masked from 'package:dplyr':
##
## n
## The following objects are masked from 'package:stats':
##
## IQR, median, sd, var
## The following objects are masked from 'package:base':
##
## max, mean, min, range, sum
data("vivienda_faltantes")
## CONOCIMIENTO DE LOS DATOS
class (vivienda_faltantes)
## [1] "spec_tbl_df" "tbl_df" "tbl" "data.frame"
name (vivienda_faltantes)
## [1] "id" "zona" "piso" "estrato" "preciom" "areaconst"
## [7] "parquea" "banios" "habitac" "tipo" "barrio" "longitud"
## [13] "latitud"
length(vivienda_faltantes$id)
## [1] 8330
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")=List of 3
## ..$ cols :List of 13
## .. ..$ id : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ zona : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ piso : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ estrato : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ preciom : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ areaconst: list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ parquea : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ banios : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ habitac : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ tipo : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ barrio : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ longitud : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ latitud : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## ..$ default: list()
## .. ..- attr(*, "class")= chr [1:2] "collector_guess" "collector"
## ..$ delim : chr ","
## ..- attr(*, "class")= chr "col_spec"
## - attr(*, "problems")=<externalptr>
# Se identifico que la muestra es un dataframe
# Se identificaron los nombre de las variables
# La muestra de los datos contiene 8330 inmubles con 13 parametros diferentes
table(is.na(vivienda_faltantes))
##
## FALSE TRUE
## 104011 4279
# Se identificaron 4279 registros sin informacion
colSums(is.na(vivienda_faltantes))
## id zona piso estrato preciom areaconst parquea banios
## 3 3 2641 3 2 3 1606 3
## habitac tipo barrio longitud latitud
## 3 3 3 3 3
## ORDENAMIENTO Y LIMPIEZA DE DATOS
# Se identifico que los datos con mayor numero de faltantes es el piso y el parqueadero.
# Con el fin de no perder informacion importante los inmuebles sin piso se coloca 1
# Con el fin de no perder informacion importante los inmuebles sin parqueadero se coloca 0
vivienda_faltantes$piso[is.na(vivienda_faltantes$piso)] <- 1
vivienda_faltantes$parquea[is.na(vivienda_faltantes$parquea)] <- 0
# Se eliminan los datos donde no tengamos informacion de precio o area
library(naniar)
gg_miss_var(vivienda_faltantes)
VIM::aggr(vivienda_faltantes, cex.axis = 0.5, cex.lab= 0.8)
# Detectados la proporción de datos faltantes procederemos como una primera estrategia
Vivienda_sinNA <- na.omit(vivienda_faltantes)
str(Vivienda_sinNA)
## spc_tbl_ [8,327 × 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ id : num [1:8327] 8312 8311 8307 8296 8297 ...
## $ zona : chr [1:8327] "Zona Oeste" "Zona Oeste" "Zona Oeste" "Zona Sur" ...
## $ piso : num [1:8327] 4 1 1 2 1 1 2 1 1 2 ...
## $ estrato : num [1:8327] 6 6 5 3 5 5 6 5 5 5 ...
## $ preciom : num [1:8327] 1300 480 1200 220 330 1350 305 480 275 285 ...
## $ areaconst: num [1:8327] 318 300 800 150 112 390 125 280 74 120 ...
## $ parquea : num [1:8327] 2 1 4 1 2 8 2 4 1 2 ...
## $ banios : num [1:8327] 4 4 7 2 4 10 3 4 2 4 ...
## $ habitac : num [1:8327] 2 4 5 4 3 10 3 4 3 3 ...
## $ tipo : chr [1:8327] "Apartamento" "Casa" "Casa" "Casa" ...
## $ barrio : chr [1:8327] "arboleda" "normandía" "miraflores" "el guabal" ...
## $ longitud : num [1:8327] -76576 -76571 -76568 -76565 -76565 ...
## $ latitud : num [1:8327] 3454 3454 3455 3417 3408 ...
## - attr(*, "spec")=List of 3
## ..$ cols :List of 13
## .. ..$ id : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ zona : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ piso : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ estrato : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ preciom : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ areaconst: list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ parquea : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ banios : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ habitac : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ tipo : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ barrio : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ longitud : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ latitud : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## ..$ default: list()
## .. ..- attr(*, "class")= chr [1:2] "collector_guess" "collector"
## ..$ delim : chr ","
## ..- attr(*, "class")= chr "col_spec"
## - attr(*, "problems")=<externalptr>
## - attr(*, "na.action")= 'omit' Named int [1:3] 8320 8321 8322
## ..- attr(*, "names")= chr [1:3] "8320" "8321" "8322"
# una vez eliminados los NA, la muestra paso de 8330x13 a 8327x13 que no representa una afectacion significativa en los datos
# Se estandariza el nombre de la variable tipo
Vivienda_sinNA <- Vivienda_sinNA %>% mutate(tipo=recode(tipo,"apto"="Apartamento","CASA"="Casa","casa"="Casa", "APARTAMENTO"="Apartamento"))
Análisis Descriptivo
En la revisión de la información se identificaron 4279 registros sin información, se identificó que los datos con mayor número de faltantes es el piso y el parqueadero. Con el fin de no perder información importante los inmuebles sin piso se coloca 1 y los inmuebles sin parqueadero se coloca 0. Asi mismo se evidencio que en la variable tipo el nombre no era estándar por lo que se modificó a nombres estándar y se eliminan los registros sin datos. Con la depuración de la información la base de datos a trabajar quedo con 8327 registros y 13 con una afectación del 0.03% de datos excluidos.
Tipo de inmueble
Se encontro que la base cuenta con 5.106 Apartamentos el 61.3% y 3.221 casas el 38.7%
tipo_inmueble <- table(Vivienda_sinNA$tipo)
pie(tipo_inmueble)
table(tipo_inmueble)
## tipo_inmueble
## 3221 5106
## 1 1
Zona
La zona con mayor oferta de inmuebles es la zona Sur con 4.726, seguida de la zona norte con 1922 y la zona oeste con 1204, miestras que las zonas con menor numero de inmuebles con la zona oriente con 351 y la zona centro con 124 inmuebles
inmuebles_zonas <- table(Vivienda_sinNA$zona)
pie(inmuebles_zonas)
table(inmuebles_zonas)
## inmuebles_zonas
## 124 351 1204 1922 4726
## 1 1 1 1 1
Precio M2
Al analizar los precios de los inmuebles se estimo el precio del metro cuadrado (preciom/areaconst), econtrando que el precio del metro cuadrado mas alto esta en la zona Oeste con un promedio de precio de 3.6Millones, seguida por la zona sur con 2.7 millones, la zona norte con 2.4, la zona centro con 1.7 millones y finalmente la zona oriente con 1.4 millones por metro cuadrado.
# Se contruye variable de precio por metro cuadrado para identificar comportamiento del mercado por zona
Vivienda_sinNA$precio_m2 <- Vivienda_sinNA$preciom/Vivienda_sinNA$areaconst
# se estima el promedio precio zona de la muestra
promedio_preciom_zona <- tapply(Vivienda_sinNA$precio_m2, Vivienda_sinNA$zona, mean)
precio_promM2 <- data.frame(zona = names(promedio_preciom_zona),
promedio_preciom = unlist(promedio_preciom_zona))
library(ggplot2)
ggplot(precio_promM2, aes_string(x = "zona", y = "promedio_preciom")) +
geom_bar(stat = "identity") +
labs(title = "Promedio precio M2 por zona",
x = "Zona",
y = "Millones de Pesos",
show.legend = TRUE)
## Warning: `aes_string()` was deprecated in ggplot2 3.0.0.
## ℹ Please use tidy evaluation idioms with `aes()`.
## ℹ See also `vignette("ggplot2-in-packages")` for more information.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
El precio del metro cuadrado promedio de los inmuebles es de 2.7
Millones de pesos; el valor maximo es de 9.3 Millones, mientras que el
valor mas bajo es de 0.15 Millones; por lo que el rango es de 9.3 que
evidencia una alta dispercion de los datos.
x = Vivienda_sinNA$precio_m2
mean(x)
## [1] 2.722955
median(x)
## [1] 2.643052
max(x)
## [1] 9.468085
min(x)
## [1] 0.1461318
max(x)-min(x)
## [1] 9.321953
(max(x)+min(x))/2
## [1] 4.807108
quantile(x)
## 0% 25% 50% 75% 100%
## 0.1461318 1.9166667 2.6430518 3.3809524 9.4680851
Cuando comparamos los precio por M2 de los apartamentos contra el precio de las casas encontramos que el precio del metro cuadrado de los apartamentos es mayor que el de las casas, lo cual es extraño dado que en otras cuidades el precio de las casas es mayor que el de los apartamentos.
boxplot(Vivienda_sinNA$precio_m2~Vivienda_sinNA$tipo,
main="Precios M2 por tipo de vivienda",
ylab = ("Precio x millon")
)
Analizando el precio del metro cuadrado por area encontramos que entre
mas area tiene un inmueble menor es el precio M2, en inmubles de mas de
500M2, que se evidencia en siguiente grafico:
ggplot(data = Vivienda_sinNA) + geom_point(mapping = aes(x =precio_m2, y =areaconst)) +
labs(title = "Distribucion por precio y area", x = "Precio", y = "Área")
El precio medio por extrato nos arrojo que el estrato 6 tiene su precio
medio en 3.6 millones, el estrato 5 en 2.8 millones, el estrato 4 en 2.4
y el estrato 3 en 1.8 millones como se aprecia en la grafica 7, sin
embargo el numero de inmuebles en oferta por estratos en 6 son 1992 en
estrato 5 2751, en estrato 4 2131,en estrato 3 1453.
promedio_preciom_estrato <- tapply(Vivienda_sinNA$precio_m2, Vivienda_sinNA$estrato, mean)
precio_prom_estrato <- data.frame(zona = names(promedio_preciom_estrato),
promedio_preciom = unlist(promedio_preciom_estrato))
library(ggplot2)
ggplot(precio_prom_estrato, aes_string(x = "zona", y = "promedio_preciom")) +
geom_bar(stat = "identity") +
labs(title = "Promedio precio M2 por Estrato",
x = "Zona",
y = "Millones de Pesos",
show.legend = TRUE)
table(precio_prom_estrato)
## promedio_preciom
## zona 1.76528909528226 2.45100144460002 2.78300867629297 3.6294878793412
## 3 1 0 0 0
## 4 0 1 0 0
## 5 0 0 1 0
## 6 0 0 0 1
table(Vivienda_sinNA$estrato)
##
## 3 4 5 6
## 1453 2131 2751 1992
Para analizar las variables area contruida, baños, habitaciones y parquederos se calcularon indicadores de centro para extraer informacion, encontrando que:
Area: el area maxima es de 1745 y la minima de 30 M2, el rango medio indica una alta dispercion de los datos y el cuartil se ubica entre 80 y 229
Parquedero: el numero maximo es de 10 y el minimo de 0, el rango medio indica una lata dispercion de los datos y el cuartil se ubica entre 1 y 2
Baños: el numero maximo es de 10 y el minimo de 0, el rango medio indica una lata dispercion de los datos y el cuartil se ubica entre 2 y 4
Habitaciones: el numero maximo es de 10 y el minimo de 0, el rango medio indica una lata dispercion de los datos y el cuartil se ubica entre 3 y 4
#area
xarea = Vivienda_sinNA$areaconst
mean(xarea)
## [1] 174.9876
median(xarea)
## [1] 123
max(xarea)
## [1] 1745
min(xarea)
## [1] 30
max(xarea)-min(xarea)
## [1] 1715
(max(xarea)+min(xarea))/2
## [1] 887.5
quantile(xarea)
## 0% 25% 50% 75% 100%
## 30 80 123 229 1745
#parquederos
xparquea = Vivienda_sinNA$parquea
mean(xparquea)
## [1] 1.482527
median(xparquea)
## [1] 1
max(xparquea)
## [1] 10
min(xparquea)
## [1] 0
max(xparquea)-min(xparquea)
## [1] 10
(max(xparquea)+min(xparquea))/2
## [1] 5
quantile(xparquea)
## 0% 25% 50% 75% 100%
## 0 1 1 2 10
#baños
xbanios = Vivienda_sinNA$banios
mean(xbanios)
## [1] 3.112045
median(xbanios)
## [1] 3
max(xbanios)
## [1] 10
min(xbanios)
## [1] 0
max(xbanios)-min(xbanios)
## [1] 10
(max(xbanios)+min(xbanios))/2
## [1] 5
quantile(xbanios)
## 0% 25% 50% 75% 100%
## 0 2 3 4 10
#habitaciones
xhabita = Vivienda_sinNA$habitac
mean(xhabita)
## [1] 3.60514
median(xhabita)
## [1] 3
max(xhabita)
## [1] 10
min(xhabita)
## [1] 0
max(xhabita)-min(xhabita)
## [1] 10
(max(xhabita)+min(xhabita))/2
## [1] 5
quantile(xhabita)
## 0% 25% 50% 75% 100%
## 0 3 3 4 10
Resultados
La informacion analizada muestra la mayor participacion de los apartamentos sobre las casas y con esto la gentrificacion de algunas zonas de la ciudad donde la demanda aumenta y la oferta se compensa via precios o mayor aprovechamiento de las areas.Normalmente estos procesos se dan en zonas de rapido desarrollo como es el caso de la zona sur.
Dentro de los principales hallazgos se encontro que el precio medio por metro cuadrado de los apartamentos supera al de las casas, en contravia con lo que ocurre en varias de las principales ciudades del pais.
Asi mismo se evidencia que los inmubles con mayores areas sulen castigar el precio en espacial los inmuebles de mas de 500 metros, en parte para tener una mejor rotacion en la venta de estos inmueble.
En los ultimo años y con el mayor desarrollo de apartamentos las areas se han visto afectadas lo cual a llevado a una reduccion, sin embargo dentro de la infromacion se evidencia que el area media es de 123 metros cuadros lo cual es mayor a las principales ciudades del pais.
Conclusiones
El análisis de la información disponible permite concluir:
El mercado con mayor dinamismo se centra en los estratos 4 y 5 por lo que se sugiere a la empresa B&C enfocarse en estos mercados
La zona de mayor oferta y posiblemente demanda es la zona sur de la ciudad
El inventario de inmuebles se debe centrar en apartamentos mayormente
Se sugiere que las áreas de los inmuebles estén entre 80 y 229 metros cuadrados
Se sugiere que los inmuebles a manejar tengan entre 1 y 2 parqueaderos
Se siguiere que los inmuebles a manejar tengan entre 2 y 4 baños preferiblemente
Al tratarse de un empresa de bienes raices B&C esta expuesta a las facilidades que ofrecen los inmubles nuevos como plazos para pago couta inicial, subvenciones en tasas, entre otras, por lo que se sugiere una estrategia de precios dinamica en la cual se permita rotar los inmubles que se tienen para administrar correctamente el capital de trabajo o intensificar la intermediacion con inmuebles de terceros que no demandan inverion de capital.