Entre 2022 y 2023, el mercado inmobiliario en Cali experimentó un crecimiento significativo, impulsado por el incremento poblacional, la inversión extranjera directa y el desarrollo de nuevos proyectos residenciales y comerciales. En 2022, las ventas en el sector alcanzaron los 6,700 millones de pesos, aunque en 2023 se observó una leve disminución a 6,100 millones de pesos. A pesar de esta ligera caída, se proyecta que el sector continuará expandiéndose en los próximos años, consolidándose como un pilar fundamental de la economía regional.
Este informe tiene como objetivo ofrecer un análisis detallado del mercado inmobiliario en Cali, centrándose en los precios de las viviendas en diferentes zonas de la ciudad, los tipos de viviendas más ofertadas y las características más relevantes de la oferta disponible. Se busca proporcionar una visión comprensiva de las dinámicas actuales y futuras del sector, facilitando decisiones informadas en un mercado en constante evolución.
Al abordar los datos utilizados para analizar el mercado inmobiliario en Cali, se implementaron varias técnicas para garantizar la precisión y la fiabilidad de los resultados obtenidos. Primero, se realizó un proceso de limpieza de datos para identificar y corregir errores tipográficos, inconsistencias en el formato y entradas faltantes que podrían distorsionar los análisis. Además, se identificaron y trataron los datos atípicos, que son valores significativamente alejados del resto de los datos, los cuales podrían ser el resultado de errores de registro o de eventos únicos.
Para abordar los datos faltantes, se emplearon diferentes técnicas según la naturaleza y la cantidad de información faltante. En casos donde los datos faltantes eran mínimos y no afectaban significativamente el análisis, se optó por eliminar las entradas incompletas. Sin embargo, en situaciones donde la ausencia de datos podría influir en los resultados, se aplicaron métodos de imputación, como la mediana siempre y cuando la distribución fuese no normal.
#cargar datos de viviendas en cali - y ver la tabla#
data(vivienda_faltantes)
head (vivienda_faltantes)
colSums(is.na(vivienda_faltantes)) %>%
as.data.frame()
gg_miss_var(vivienda_faltantes) # grafico de datos faltantes
Como se muestra en la figura siguiente, las variables “piso” y “parqueadero” son las que presentan el mayor número de datos faltantes. Para determinar el tipo de imputación adecuado, se realizó un análisis de la distribución de las variables numéricas. La prueba utilizada fue la curtosis, que evalúa la “altitud” y el “ancho” de las colas de la distribución en comparación con una distribución normal.
t_vivienda = table(vivienda_faltantes$tipo)
print("Tipo de viviendas más ofertadas en Cali:")
## [1] "Tipo de viviendas más ofertadas en Cali:"
t_vivienda
##
## Apartamento APARTAMENTO apto casa Casa CASA
## 5032 61 13 14 3195 12
ggplot(data = vivienda_faltantes, aes(x = tipo)) +
geom_bar() +
theme_minimal() +
labs(title = "Tipos de Viviendas mas ofertadas en Cali",
x = "Tipo de Vivienda",
y = "Frecuencia")
Como no estan estandarizados los terminos se procede a ello de la siguiente forma:
# Función para estandarizar los valores de 'tipo'
estandarizar_tipo = function(tipo) {
tipo = tolower(tipo) # Convertir a minúsculas
tipo = dplyr::recode(tipo, # Reemplazar valores específicos
"apartamento" = "Apartamento",
"apto" = "Apartamento",
"casa" = "Casa",
"CASA" = "Casa",
"APARTAMENTO" = "Apartamento")
return(tipo)
}
# Aplicar la función para unificar la columna 'tipo'#
vivienda_faltantes = vivienda_faltantes %>%
mutate(tipo = estandarizar_tipo(tipo))
# Ver los resultados
table(vivienda_faltantes$tipo)
##
## Apartamento Casa
## 5106 3221
ggplot(data = vivienda_faltantes, aes(x = zona, fill = tipo)) +
geom_bar(position = "dodge") +
labs(title = "Distribución de Tipos de Vivienda por Zona",
x = "Zona",
y = "Cantidad",
fill = "Tipo de Vivienda") +
theme_minimal()
En el mercado inmobiliario de Cali, los tipos de viviendas más ofertadas son apartamentos y casas. Según los datos recopilados, se ofertan un total de 5,106 apartamentos y 3,221 casas. Este predominio de apartamentos se debe a la alta demanda en las zonas urbanas, mientras que las casas unifamiliares siguen siendo una opción popular para quienes buscan más espacio y privacidad.
Como se muestra en la figura siguiente, las variables “piso” y “parqueadero” son las que presentan el mayor número de datos faltantes. Para determinar el tipo de imputación adecuado, se realizó un análisis de la distribución de las variables numéricas. La prueba utilizada fue la curtosis, que evalúa la “altitud” y el “ancho” de las colas de la distribución en comparación con una distribución normal.
# Calcular la curtosis del piso con el fin de determinar su distribución e imputacion#
curtosis = kurtosis(vivienda_faltantes$piso, na.rm = TRUE)
print(paste("Curtosis de 'preciom':", curtosis))
## [1] "Curtosis de 'preciom': 1.04803518541756"
ggplot(vivienda_faltantes, aes(x = piso)) +
geom_histogram(bins = 10, fill = "orange", color = "black") +
theme_minimal() +
labs(title = paste("Distribucion de Precios de Viviendas (Curtosis =", round(curtosis, 2), ")"),
x = "Precio (en millones)",
y = "Frecuencia")
## Warning: Removed 2641 rows containing non-finite outside the scale range
## (`stat_bin()`).
Un valor de curtosis de 1.05 para precio explica que la distribución es platicúrtica. Es decir, la distribución es menos pronunciada en el centro y tiene colas más cortas y menos destacadas en comparación con una distribución normal.
Al no seguir una distribución normal, se imputan los datos faltantes a traves de la mediana.
# Calculo de la mediana#
mediana_piso = median(vivienda_faltantes$piso, na.rm = TRUE)
mediana_piso
## [1] 3
# Imputar los valores con la mediana#
vivienda_faltantes$piso[is.na(vivienda_faltantes$piso)] = mediana_piso
summarytools::freq(vivienda_faltantes$piso)
## Frequencies
## vivienda_faltantes$piso
## Type: Numeric
##
## Freq % Valid % Valid Cum. % Total % Total Cum.
## ----------- ------ --------- -------------- --------- --------------
## 1 861 10.34 10.34 10.34 10.34
## 2 1450 17.41 27.74 17.41 27.74
## 3 3738 44.87 72.62 44.87 72.62
## 4 607 7.29 79.90 7.29 79.90
## 5 568 6.82 86.72 6.82 86.72
## 6 245 2.94 89.66 2.94 89.66
## 7 207 2.48 92.15 2.48 92.15
## 8 211 2.53 94.68 2.53 94.68
## 9 146 1.75 96.43 1.75 96.43
## 10 130 1.56 98.00 1.56 98.00
## 11 84 1.01 99.00 1.01 99.00
## 12 83 1.00 100.00 1.00 100.00
## <NA> 0 0.00 100.00
## Total 8330 100.00 100.00 100.00 100.00
Bajo la anterior imputación se procede a observar de nuevo los datos faltantes del archivo.
colSums(is.na(vivienda_faltantes)) %>%
as.data.frame()
el anterior muestra un cantidad predominante para la variable parqueadero parquea, por lo anterior, se procede a determinar bajo el mismo condicionante anterior.
#Curtosis de los parqueaderos#
curtosis_parquea = kurtosis(vivienda_faltantes$parquea, na.rm = TRUE)
print(paste("Curtosis de 'parquea':", curtosis_parquea))
## [1] "Curtosis de 'parquea': 8.29065224012304"
ggplot(vivienda_faltantes, aes(x = parquea)) +
geom_histogram(bins = 10, fill = "red", color = "black") +
theme_minimal() +
labs(title = paste("Distribucion de Precios de Viviendas (Curtosis =", round(curtosis_parquea, 2), ")"),
x = "Precio (en millones)",
y = "Frecuencia")
## Warning: Removed 1606 rows containing non-finite outside the scale range
## (`stat_bin()`).
Una curtosis de 8.29 para parqueaderos indica que la variable es leptocúrtica. Esto significa que la distribución tiene colas más pesadas y un pico más alto en comparación con una distribución normal. Al no seguir una distribución normal, se imputan los datos faltantes a traves de la mediana.
# Calcular la mediana del 'parqueadero' para cada.#
mediana_parquea = median(vivienda_faltantes$parquea, na.rm = TRUE)
# Imputar los valores vacíos con la mediana#
vivienda_faltantes$parquea[is.na(vivienda_faltantes$parquea)] = mediana_parquea
summarytools::freq(vivienda_faltantes$parquea)
## Frequencies
## vivienda_faltantes$parquea
## Type: Numeric
##
## Freq % Valid % Valid Cum. % Total % Total Cum.
## ----------- ------ --------- -------------- --------- --------------
## 1 3156 37.887 37.887 37.887 37.887
## 2 4084 49.028 86.915 49.028 86.915
## 3 521 6.255 93.169 6.255 93.169
## 4 386 4.634 97.803 4.634 97.803
## 5 68 0.816 98.619 0.816 98.619
## 6 68 0.816 99.436 0.816 99.436
## 7 18 0.216 99.652 0.216 99.652
## 8 17 0.204 99.856 0.204 99.856
## 9 4 0.048 99.904 0.048 99.904
## 10 8 0.096 100.000 0.096 100.000
## <NA> 0 0.000 100.000
## Total 8330 100.000 100.000 100.000 100.000
Observo los datos faltantes de nuevo, para cesiorar la realización de la imputación.
#mirar datos faltantes#
colSums(is.na(vivienda_faltantes)) %>%
as.data.frame()
#elimino filas con valores nulos#
vivienda_faltantes <- na.omit(vivienda_faltantes)
#mirar datos faltantes#
colSums(is.na(vivienda_faltantes)) %>%
as.data.frame()
La tabla anterior refleja los datos para las variables previamente expuestas, imputados mediante la mediana, dado que se trataba de variables numéricas que no seguían una distribución normal. Para las demás variables con datos faltantes, se procedió a eliminar las filas correspondientes, ya que, dado que los datos faltantes eran mínimos (con un máximo de tres datos faltantes por variable), esta eliminación no tiene un efecto significativo en el análisis.
#Precio promedio de las viviendas en diferentes zonas de Cali#
p_pzona = aggregate(vivienda_faltantes$preciom,
by=list(vivienda_faltantes$zona), FUN=mean, na.rm=TRUE)
colnames(p_pzona) = c("Zona", "Precio_Promedio")
print("Precios promedio de las viviendas por zona:")
## [1] "Precios promedio de las viviendas por zona:"
p_pzona
::: {align=“justify”} La Zona Oeste la más costosa y la Zona Oriente la más económica. La Zona Sur presenta la mayor actividad inmobiliaria con el mayor número de ofertas, mientras que la Zona Centro tiene la menor cantidad de ofertas. No hay una relación directa clara entre el precio promedio y el número de ofertas, ya que zonas con precios altos como la Zona Oeste tienen una cantidad considerable de ofertas, y la Zona Norte también muestra una alta oferta pese a tener un precio intermedio.:::
# Gráfico de tipos de viviendas más ofertadas#
ggplot(data = vivienda_faltantes, aes(x = tipo)) +
geom_bar() +
theme_minimal() +
labs(title = "Tipos de Viviendas mas ofertadas en Cali",
x = "Tipo de Vivienda",
y = "Frecuencia")
#Gráfico de precios por zona#
ggplot(data = vivienda_faltantes, aes(x = zona, y = preciom)) +
geom_boxplot() +
theme_minimal() +
labs(title = "Distribucion de Precios de Viviendas por Zona en Cali",
x = "Zona",
y = "Precio (en millones)")
La Zona Oeste la más costosa y la Zona Oriente la más económica. La Zona Sur presenta la mayor actividad inmobiliaria con el mayor número de ofertas, mientras que la Zona Centro tiene la menor cantidad de ofertas. No hay una relación directa clara entre el precio promedio y el número de ofertas, ya que zonas con precios altos como la Zona Oeste tienen una cantidad considerable de ofertas, y la Zona Norte también muestra una alta oferta pese a tener un precio intermedio.
paleta6=c("#447270", "#6B9493", "#F6E271", "#F6B916", "#F69312", "#BC6C25")
p1=ggplot(vivienda_faltantes, aes(y=preciom, x=zona))+
geom_jitter(color="#034A94", size=1, alpha=0.9) +
aes(color=paleta6)+
labs(title = "Dispercion del precio por zona",
y= "precio",
x= "zona")+
ylim(0,1000)
p1
## Warning: Removed 575 rows containing missing values or values outside the scale range
## (`geom_point()`).
conteo_por_zona = vivienda_faltantes %>%
count(zona)
# Muestra el conteo por zona
print(conteo_por_zona)
## # A tibble: 5 × 2
## zona n
## <chr> <int>
## 1 Zona Centro 124
## 2 Zona Norte 1922
## 3 Zona Oeste 1204
## 4 Zona Oriente 351
## 5 Zona Sur 4726
La mayor cantidad de viviendas se encuentra en la zona sur, la segunda zona con mayor cantidad de viviendas es la zona norte.
#Gráfico de dispersión de precio vs área construida#
ggplot(data = vivienda_faltantes, aes(x = areaconst, y = preciom)) +
geom_point() +
theme_minimal() +
labs(title = "Relacion entre Area Construida y Precio de Viviendas en Cali",
x = "Area Construida (m2)",
y = "Precio (en millones)")
La dispersión de precios de las viviendas muestra una variabilidad en los estratos. El estrato 5, con 2,751 viviendas, presenta la mayor dispersión, seguido por el estrato 4 con 2,131 viviendas. En el estrato 6 se encuentran 1,992 viviendas, mientras que el estrato 3 cuenta con 1,453 viviendas. En cuanto a la distribución de barrios, su distribución por estratos es el siguiente: el estrato 3 alberga 262 barrios, el estrato 4 tiene 171 barrios, el estrato 5 incluye 169 barrios y el estrato 6 cuenta con 84 barrios.
#Datos atipicos##
# Calcular estadísticas descriptivas por zona#
estadisticas_por_zona <- vivienda_faltantes %>%
group_by(zona) %>%
summarise(
media = mean(preciom, na.rm = TRUE),
mediana = median(preciom, na.rm = TRUE),
desviacion = sd(preciom, na.rm = TRUE),
q1 = quantile(preciom, 0.25, na.rm = TRUE),
q3 = quantile(preciom, 0.75, na.rm = TRUE),
IQR = q3 - q1
)
estadisticas_por_zona
La columna atipico contiene un valor lógico (TRUE/FALSE)
que indica si el valor de preciom es un valor atípico
(outlier) según la regla del rango intercuartílico (IQR). Un valor se
considera atípico si es menor que q1 - 1.5 * IQR o mayor
que q3 + 1.5 * IQR. La Zona Oeste la más costosa y la Zona
Oriente la más económica. La Zona Sur presenta la mayor actividad
inmobiliaria con el mayor número de ofertas, mientras que la Zona Centro
tiene la menor cantidad de ofertas. No hay una relación directa clara
entre el precio promedio y el número de ofertas, ya que zonas con
precios altos como la Zona Oeste tienen una cantidad considerable de
ofertas, y la Zona Norte también muestra una alta oferta pese a tener un
precio intermedio.
# Detectar atípicos usando el IQR#
vivienda_faltantes_atipicos = vivienda_faltantes %>%
left_join(estadisticas_por_zona, by = "zona") %>%
mutate(
atipico = preciom < (q1 - 1.5 * IQR) | preciom > (q3 + 1.5 * IQR)
)
# Ver datos atípicos
datos_atipicos <- vivienda_faltantes_atipicos %>%
filter(atipico)
datos_atipicos
# Gráfico de cajas con atípicos#
ggplot(vivienda_faltantes, aes(x = zona, y = preciom)) +
geom_boxplot(outlier.colour = "red", outlier.shape = 16) +
theme_minimal() +
labs(title = "Distribucion de Precios por Zona con Datos Atipicos",
x = "Zona",
y = "Precio (en millones)")
# Imputar datos atípicos con la mediana#
vivienda_faltantes_imputados = vivienda_faltantes_atipicos %>%
mutate(preciom = ifelse(atipico, mediana, preciom))
ggplot(vivienda_faltantes_imputados, aes(x = zona, y = preciom)) +
geom_boxplot(outlier.colour = "red", outlier.shape = 16) +
theme_minimal() +
labs(title = "Distribucion de Precios por Zona con Datos Atipicos arreglados con la mediana",
x = "Zona",
y = "Precio (en millones)")
Finalmente, los datos atípicos fueron imputados con la mediana para suavizar la distribución y mejorar la calidad del análisis. Sin embargo, es importante destacar que este proceso no se aplicó al análisis descriptivo, ya que los datos atípicos pueden reflejar características particulares de las viviendas, como su estado físico o ubicación geográfica, que pueden justificar un valor más alto y son relevantes para comprender las dinámicas del mercado inmobiliario en Cali.
paleta7=c("#447270", "#6B9493", "#F6E271", "#F6B916", "#F69312", "#BC6C25")
p3=ggplot(vivienda_faltantes_imputados, aes(y=preciom, x=estrato))+
geom_jitter(color="#447270", size=1, alpha=0.9) +
aes(color=paleta7)+
labs(title = " ",
y= "precio",
x= "Estrato")+
ylim(0,1500)
p3
## Warning: Removed 21 rows containing missing values or values outside the scale range
## (`geom_point()`).
conteo_barrios_por_estrato = vivienda_faltantes_imputados %>%
group_by(estrato) %>%
summarise(
cantidad_barrios = n_distinct(barrio) # Contar barrios únicos por estrato
)
print(conteo_barrios_por_estrato)
## # A tibble: 4 × 2
## estrato cantidad_barrios
## <dbl> <int>
## 1 3 262
## 2 4 171
## 3 5 169
## 4 6 84
vivienda_faltantes_imputados$estrato = as.factor(vivienda_faltantes_imputados$estrato)
conteo=vivienda_faltantes_imputados %>%
count(estrato)
conteo
En cuanto a la distribución de barrios, su distribución por estratos es el siguiente: el estrato 3 alberga 262 barrios, el estrato 4 tiene 171 barrios, el estrato 5 incluye 169 barrios y el estrato 6 cuenta con 84 barrios.
p2 = ggplot(vivienda_faltantes_imputados, aes(y = preciom, x = estrato)) +
geom_jitter(color = "#447270", size = 1, alpha = 0.9) +
geom_text(data = conteo , aes(label = n, x = estrato, y = 0), vjust = -0.5, color = "black") +
labs(title = " ",
y = "Precio",
x = "Estrato") +
ylim(0, 1500)
p2
## Warning: Removed 21 rows containing missing values or values outside the scale range
## (`geom_point()`).
El mercado inmobiliario en Cali revela una significativa variabilidad en precios según la zona, con el Oeste siendo la más cara y el Oriente la más económica, mientras que la Zona Sur muestra una alta actividad inmobiliaria. Los apartamentos predominan en el mercado, con una oferta mucho mayor que la de las casas, reflejando una alta demanda en áreas urbanas y ofreciendo oportunidades para desarrollos residenciales. La relación directa entre el tamaño de la vivienda y su precio subraya la importancia de ofrecer opciones amplias para captar a quienes están dispuestos a pagar más. En cuanto a los estratos, el estrato 5 presenta la mayor dispersión de precios y el estrato 3 tiene el mayor número de barrios, indicando una alta fragmentación en ese estrato.
Por otro lado, la variabilidad en el número de barrios por estrato indica diferencias en la concentración de propiedades. El estrato 3, con su gran cantidad de barrios, puede indicar un mercado más fragmentado y competitivo, mientras que los estratos superiores, con menos barrios, pueden reflejar una mayor concentración de propiedades y, posiblemente, una demanda más homogénea.