Maria comenzó como agente de bienes raíces en Cali hace 10 años. Después de laborar dos años para una empresa nacional, se traslado a Bogotá y trabajó para otra agencia de bienes raíces. Sus amigos y familiares la convencieron de que con su experiencia y conocimientos del negocio debía abrir su propia agencia. Terminó por adquirir la licencia de intermediario y al poco tiempo fundó su propia compañía, C&A (Casas y Apartamentos) en Cali. Santiago y Lina, dos vendedores de la empresa anterior aceptaron trabajar en la nueva compaña. En la actualidad ocho agentes de bienes raíces colaboran con ella en C&A.
Actualmente las ventas de bienes raíces en Cali se han visto disminuidas de manera significativa en lo corrido del año. Durante este periodo muchas instituciones bancarias de ahorro y vivienda están prestando grandes sumas de dinero para la industria y la construcción comercial y residencial. Cuando el efecto producto de las tensiones políticas y sociales disminuya, se espera que la actividad económica de este sector se reactive.
Hace dos días, María recibió una carta solicitando asesoría para la compra de dos viviendas por parte de una compañía internacional que desea ubicar a dos de sus empleados con sus familias en la ciudad. Las solicitudes incluyen las siguientes condiciones:
# Cargue de librerias
library(dlookr); library(paqueteMODELOS); library(leaflet); library(VIM)
library(dplyr); library(ggplot2); library(gridExtra); library(dplyr)
library(plotly); library(broom); library(tidyr)
# Cargue de los datos
data("vivienda"); data <- vivienda; head(vivienda)
## # A tibble: 6 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1147 Zona O… <NA> 3 250 70 1 3 6
## 2 1169 Zona O… <NA> 3 320 120 1 2 3
## 3 1350 Zona O… <NA> 3 350 220 2 2 4
## 4 5992 Zona S… 02 4 400 280 3 5 3
## 5 1212 Zona N… 01 5 260 90 1 2 3
## 6 1724 Zona N… 01 5 240 87 1 3 3
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
Para facilitar una visualización más clara de la base de datos, se filtra y se proyecta en el mapa para confirmar que la selección de Casas en la Zona Norte sea la correcta.
# 1.1 Filtro a la base de datos, Seleccion de Zona Norte y Tipo: Casa
data_apartamentos <- subset(data, zona == "Zona Sur" & tipo == "Apartamento") # Filtro por filas
head(data_apartamentos, 3) # Mostrar los primeros 3 registros
## # A tibble: 3 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 5098 Zona S… 05 4 290 96 1 2 3
## 2 698 Zona S… 02 3 78 40 1 1 2
## 3 8199 Zona S… <NA> 6 875 194 2 5 3
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
table(data_apartamentos$zona); table(data_apartamentos$tipo) # Generar algunas tablas para comprobar la consulta
##
## Zona Sur
## 2787
##
## Apartamento
## 2787
leaflet(data_apartamentos %>% filter(!is.na(latitud), !is.na(longitud))) %>%
addTiles() %>% addCircleMarkers(~longitud, ~latitud, color = "blue", radius = 5) %>%
setView(lng = mean(data_apartamentos$longitud, na.rm = TRUE), lat = mean(data_apartamentos$latitud, na.rm = TRUE), zoom = 12) %>%
addControl("<h3>Apartamentos Zona Sur - BD Sin Depurar</h3>", position = "topleft")
Se observa que hay numerosos puntos que no corresponden con la ubicación de Apartamentos en la Zona Sur de Cali. Para depurar los datos y realizar un análisis más preciso, se aplicó un filtro de valores atípicos utilizando los cuartiles, con el objetivo de reducir el margen de error en la ubicación.
# Eliminación de columnas innecesarias para el análisis
data_apartamentos <- data_apartamentos %>% select(preciom, areaconst, estrato, habitaciones, parqueaderos, banios, longitud, latitud)
# Convertir la variable 'estrato' en categórica
data_apartamentos$estrato <- as.factor(data_apartamentos$estrato); str(data_apartamentos$estrato)
## Factor w/ 4 levels "3","4","5","6": 2 1 4 1 1 2 1 1 1 2 ...
# Tratamiento de valores nulos
data_apartamentos <- data_apartamentos[data_apartamentos$habitaciones != 0 & data_apartamentos$banios != 0, ]
Se llevó a cabo un análisis en el que se determinó que las viviendas sin baños ni habitaciones podrían clasificarse como lotes o parqueaderos. Por esta razón, se excluyeron estos datos del análisis.
# Tratamiento de outliers de las variables longitud y latitud
###################################################################
# Inicializar variables
threshold <- 0.01; max_iter <- 10; data_original <- data_apartamentos
percent_outliers <- numeric(max_iter); iterations <- numeric(max_iter)
# Filtrar y registrar datos
for (iter in 1:max_iter) {
q25_lat <- quantile(data_apartamentos$latitud, 0.25, na.rm = TRUE)
q75_lat <- quantile(data_apartamentos$latitud, 0.75, na.rm = TRUE)
iqr_lat <- IQR(data_apartamentos$latitud, na.rm = TRUE)
q25_lon <- quantile(data_apartamentos$longitud, 0.25, na.rm = TRUE)
q75_lon <- quantile(data_apartamentos$longitud, 0.75, na.rm = TRUE)
iqr_lon <- IQR(data_apartamentos$longitud, na.rm = TRUE)
data_apartamentos <- data_apartamentos %>%
filter(between(latitud, q25_lat - 1.5 * iqr_lat, q75_lat + 1.5 * iqr_lat),
between(longitud, q25_lon - 1.5 * iqr_lon, q75_lon + 1.5 * iqr_lon))
percent_outliers[iter] <- (1 - nrow(data_apartamentos) / nrow(data_original)) * 100
iterations[iter] <- iter
if ((1 - nrow(data_apartamentos) / nrow(data_original)) <= threshold) break
}
# Graficar porcentaje de valores atípicos
ggplot(data.frame(Iteration = iterations[1:iter], PercentOutliers = percent_outliers[1:iter]),
aes(x = Iteration, y = PercentOutliers)) +
geom_line() + geom_point() +
labs(title = "Porcentaje de Valores Atípicos por Iteración", x = "Número de Iteración", y = "Porcentaje de Valores Atípicos (%)") +
theme_minimal()
# Crear el mapa
leaflet(data_apartamentos %>% filter(!is.na(latitud), !is.na(longitud))) %>%
addTiles() %>%
addCircleMarkers(~longitud, ~latitud, color = "blue", radius = 5) %>%
setView(lng = mean(data_apartamentos$longitud, na.rm = TRUE), lat = mean(data_apartamentos$latitud, na.rm = TRUE), zoom = 12) %>%
addControl(paste0("<h3>Apartamentos Zona Sur - Iteración ", iter, "</h3>"), position = "topleft")
Podemos observar que, tras 5 iteraciones, el filtro de datos por cuartiles aplicado a las variables de latitud y longitud se estabilizó. Además, el mapa resultante muestra una visualización más depurada y concentrada en la Zona Sur, lo que permitirá realizar un análisis más preciso del modelo, sin embargo aun se observan valores atipicos que no se lograron corregir con este metodo.
data_apartamentos <- data_apartamentos %>% select(preciom, areaconst, estrato, habitaciones, parqueaderos, banios)
# Tratamiento de NA
###################################################################
# Calcular la correlación entre parqueaderos y preciom antes de la imputación
cor_before <- cor(data_apartamentos$parqueaderos, data_apartamentos$preciom, use = "complete.obs")
# Recuento y porcentaje de NA por variable sin imputación
na_summary <- data_apartamentos %>% summarise(across(everything(), ~sum(is.na(.)))) %>%
pivot_longer(cols = everything(), names_to = "variable", values_to = "count_na") %>%
mutate(percent_na = count_na / nrow(data_apartamentos) * 100)
print(na_summary)
## # A tibble: 6 × 3
## variable count_na percent_na
## <chr> <int> <dbl>
## 1 preciom 0 0
## 2 areaconst 0 0
## 3 estrato 0 0
## 4 habitaciones 0 0
## 5 parqueaderos 357 14
## 6 banios 0 0
Tenemos 357 datos faltantes en la variable “parqueaderos”, lo que representa el 14% del total. Se decidió realizar una imputación utilizando la técnica de KNN para abordar este problema.
# Imputar con KNN
##############################################
data_apartamentos_imputado <- kNN(data_apartamentos, variable = "parqueaderos")
# Comparar distribuciones
data_apartamentos %>% mutate(source = ifelse(is.na(parqueaderos), "Original NA", "Original Not NA")) %>%
bind_rows(data_apartamentos_imputado %>% mutate(source = "Imputado")) %>% ggplot(aes(x = parqueaderos, fill = source)) +
geom_density(alpha = 0.5) + labs(title = "Distribución de 'parqueaderos': Original vs Imputado", x = "Valor de parqueaderos", y = "Densidad") + theme_minimal()
# Recuento y porcentaje de NA por variable con imputación
na_summary <- data_apartamentos_imputado %>% summarise(across(everything(), ~sum(is.na(.)))) %>%
pivot_longer(cols = everything(), names_to = "variable", values_to = "count_na") %>%
mutate(percent_na = count_na / nrow(data_apartamentos) * 100)
print(na_summary)
## # A tibble: 7 × 3
## variable count_na percent_na
## <chr> <int> <dbl>
## 1 preciom 0 0
## 2 areaconst 0 0
## 3 estrato 0 0
## 4 habitaciones 0 0
## 5 parqueaderos 0 0
## 6 banios 0 0
## 7 parqueaderos_imp 0 0
# Calcular la correlación entre parqueaderos y preciom después de la imputación
cor_after <- cor(data_apartamentos_imputado$parqueaderos, data_apartamentos_imputado$preciom, use = "complete.obs")
# Crear un dataframe con las correlaciones antes y después
correlation_comparison <- data.frame(
Metodo = c("Antes de imputación", "Después de imputación"),
Correlacion = c(cor_before, cor_after)
)
# Mostrar el dataframe con las correlaciones
print(correlation_comparison)
## Metodo Correlacion
## 1 Antes de imputación 0.7322150
## 2 Después de imputación 0.7472423
Después de la imputación, no quedan valores faltantes en las variables, lo que confirma la efectividad del método KNN utilizado. Además, la correlación entre “parqueaderos” y “preciom” aumentó de 0.7322150 a 0.7472423, no es un cambio significativo pero ayudara a la calidad y precisión del análisis, lo que resulta en un modelo predictivo más robusto.
# 2.1. Análisis de Variables Numéricas
###################################################################
# 2.1.1. Matriz de Correlación
# Seleccionar variables numéricas
datos_numericos <- data_apartamentos %>% select(preciom, areaconst, banios, habitaciones, parqueaderos)
# Calcular matriz de correlación
corr_matrix <- cor(datos_numericos, use = "complete.obs")
# Convertir a formato largo
corr_long <- as.data.frame(as.table(corr_matrix))
# Graficar heatmap
plot_ly(corr_long, x = ~Var2, y = ~Var1, z = ~Freq, type = 'heatmap',
colorscale = 'Viridis', text = ~paste0(round(Freq, 2)), texttemplate = '%{text}') %>%
layout(title = 'Matriz de Correlación entre Variables Numéricas',
xaxis = list(title = 'Variables'),
yaxis = list(title = 'Variables'))
Matriz de Correlación: La matriz de correlación entre las variables numéricas muestra relaciones importantes entre ellas:
Área Construida y Parqueaderos tienen la correlación más fuerte con el Precio (0.73 cada uno). Estas son las variables más influyentes en el valor de la propiedad.
Baños también muestra una correlación moderada con el precio (0.71), indicando que un mayor número de baños generalmente se asocia con precios más altos.
Habitaciones tiene una correlación más baja con el precio (0.31), sugiriendo que, aunque influye, su impacto es menor comparado con el área construida y los parqueaderos.
# 2.1.2. Gráficos de Dispersión
# Crear gráficos de dispersión
plots_numeric <- list(
plot_ly(data_apartamentos, x = ~areaconst, y = ~preciom, type = 'scatter', mode = 'markers',
name = 'Precio vs Área Construida') %>%
layout(title = 'Precio vs Área Construida',
xaxis = list(title = 'Área Construida'),
yaxis = list(title = 'Precio'),
legend = list(orientation = 'h', x = 0.5, xanchor = 'center', y = -0.2)), # Leyenda debajo del título
plot_ly(data_apartamentos, x = ~banios, y = ~preciom, type = 'scatter', mode = 'markers',
name = 'Precio vs Número de Baños') %>%
layout(title = 'Precio vs Número de Baños',
xaxis = list(title = 'Número de Baños'),
yaxis = list(title = 'Precio'),
legend = list(orientation = 'h', x = 0.5, xanchor = 'center', y = -0.2)), # Leyenda debajo del título
plot_ly(data_apartamentos, x = ~habitaciones, y = ~preciom, type = 'scatter', mode = 'markers',
name = 'Precio vs Número de Habitaciones') %>%
layout(title = 'Precio vs Número de Habitaciones',
xaxis = list(title = 'Número de Habitaciones'),
yaxis = list(title = 'Precio'),
legend = list(orientation = 'h', x = 0.5, xanchor = 'center', y = -0.2)), # Leyenda debajo del título
plot_ly(data_apartamentos, x = ~parqueaderos, y = ~preciom, type = 'scatter', mode = 'markers',
name = 'Precio vs Número de Parqueaderos') %>%
layout(title = 'Precio vs Número de Parqueaderos',
xaxis = list(title = 'Número de Parqueaderos'),
yaxis = list(title = 'Precio'),
legend = list(orientation = 'h', x = 0.5, xanchor = 'center', y = -0.2)) # Leyenda debajo del título
)
# Mostrar gráficos en un layout de 2x2
subplot(plots_numeric, nrows = 2, margin = 0.05) %>%
layout(title = 'Diagramas de Dispersión de Variables Numéricas',
showlegend = TRUE) # Asegúrate de que la leyenda se muestre
Diagramas de Dispersión:
# 2.2.1. Realizar el análisis ANOVA
anova_result <- aov(preciom ~ estrato, data = data_apartamentos)
summary(anova_result)
## Df Sum Sq Mean Sq F value Pr(>F)
## estrato 3 49153796 16384599 963.2 <2e-16 ***
## Residuals 2546 43308274 17010
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# 2.2.2. Boxplot para Estrato
# Definir colores para cada nivel de la variable estrato
colores_estrato <- c("red", "blue", "green", "orange") # Ajusta los colores según sea necesario
# Crear boxplot para la variable estrato con colores diferenciados
boxplot_estrato <- plot_ly(data_apartamentos, x = ~estrato, y = ~preciom, type = 'box', color = ~estrato, colors = colores_estrato) %>%
layout(title = 'Distribución del Precio por Estrato',
xaxis = list(title = 'Estrato'), yaxis = list(title = 'Precio'))
# Mostrar el boxplot
boxplot_estrato
Incremento del Precio con el Estrato: A medida que el estrato aumenta (de 3 a 6), también se observa un incremento en el precio de las viviendas. Esto sugiere una relación directa entre el estrato socioeconómico y el valor de la propiedad, donde los estratos más altos tienden a tener precios más elevados.
Significancia Estadística: La tabla que acompaña la gráfica muestra un resultado de ANOVA con un valor de p muy pequeño (<2e-16), lo que indica que las diferencias en el precio entre los diferentes estratos son estadísticamente significativas. Esto respalda la observación visual de que el estrato tiene un impacto considerable en el precio de las viviendas.
modelo <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = data_apartamentos)
summary(modelo) # Resumen del modelo
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = data_apartamentos)
##
## Residuals:
## Min 1Q Median 3Q Max
## -986.47 -40.57 -0.32 37.32 900.26
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -32.91496 13.59069 -2.422 0.01552 *
## areaconst 1.20606 0.05254 22.956 < 2e-16 ***
## estrato4 30.62408 9.83109 3.115 0.00186 **
## estrato5 49.72514 9.89218 5.027 5.40e-07 ***
## estrato6 196.32714 11.56796 16.972 < 2e-16 ***
## habitaciones -17.28858 3.98984 -4.333 1.54e-05 ***
## parqueaderos 75.88290 4.52495 16.770 < 2e-16 ***
## banios 40.19756 3.44246 11.677 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 92.65 on 2185 degrees of freedom
## (357 observations deleted due to missingness)
## Multiple R-squared: 0.7731, Adjusted R-squared: 0.7723
## F-statistic: 1063 on 7 and 2185 DF, p-value: < 2.2e-16
coeficientes <- tidy(modelo); print(coeficientes) # Obtener coeficientes y p-valores
## # A tibble: 8 × 5
## term estimate std.error statistic p.value
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 (Intercept) -32.9 13.6 -2.42 1.55e- 2
## 2 areaconst 1.21 0.0525 23.0 1.18e-104
## 3 estrato4 30.6 9.83 3.12 1.86e- 3
## 4 estrato5 49.7 9.89 5.03 5.40e- 7
## 5 estrato6 196. 11.6 17.0 8.79e- 61
## 6 habitaciones -17.3 3.99 -4.33 1.54e- 5
## 7 parqueaderos 75.9 4.52 16.8 1.80e- 59
## 8 banios 40.2 3.44 11.7 1.33e- 30
Modelo de Regresión: El modelo de regresión tiene un R-cuadrado múltiple de 0.6057 y un R-cuadrado ajustado de 0.5985, lo que indica que aproximadamente el 60% de la variabilidad en el precio puede explicarse por las variables independientes incluidas en el modelo. Esto sugiere que el modelo es moderadamente bueno para predecir el precio basado en las variables seleccionadas.
Intercepto: Es significativo con un p-valor de 0.0155, y su coeficiente de -32.9 indica que, cuando todas las variables independientes son cero, el precio predicho sería negativo, lo que sugiere que no tiene una interpretación práctica directa en este contexto.
areaconst (Área Construida): Tiene un coeficiente de 1.21, que es altamente significativo (p-valor de 1.18e-104), lo que indica que por cada unidad adicional de área construida, el precio aumenta en 1.21 unidades, manteniendo las demás variables constantes.
Estratos: Todos los coeficientes asociados con los estratos (4, 5, 6) son significativos y positivos:
Habitaciones: Tiene un coeficiente negativo de -17.3, que es estadísticamente significativo (p-valor de 1.54e-5), lo que sugiere que, contrariamente a lo que podría esperarse, un mayor número de habitaciones está asociado con una disminución en el precio, posiblemente debido a que más habitaciones podrían estar asociadas con un diseño menos eficiente o propiedades más antiguas.
Parqueaderos: Tiene un coeficiente significativo de 75.9 (p-valor de 1.80e-59), lo que indica que tener más parqueaderos aumenta considerablemente el precio de la propiedad.
Baños: Es significativo con un coeficiente de 40.2 (p-valor de 1.33e-30), lo que sugiere que el número de baños tiene un impacto positivo importante en el precio, aunque es menos pronunciado en comparación con el área construida y los estratos.
# 4. Validación de supuestos
###################################################################
# 4.1 Linealidad y Homoscedasticidad: Graficar residuos vs. valores ajustados
###################################################################
ggplot(modelo, aes(x = .fitted, y = .resid)) +
geom_point() +
geom_hline(yintercept = 0, linetype = "dashed", color = "red") +
labs(title = "Residuos vs. Valores Ajustados", x = "Valores Ajustados", y = "Residuos")
###################################################################
# 4.2 Independencia de los Errores: Gráfico de residuos vs. orden
###################################################################
ggplot(modelo, aes(x = seq_along(.resid), y = .resid)) +
geom_point() +
geom_hline(yintercept = 0, linetype = "dashed", color = "red") +
labs(title = "Residuos vs. Orden", x = "Orden", y = "Residuos")
###################################################################
# 4.3 Normalidad de los Errores: Histograma de residuos y Q-Q plot
###################################################################
par(mfrow = c(1, 2)) # Configurar para múltiples gráficos
hist(modelo$residuals, main = "Histograma de Residuos", xlab = "Residuos")
qqnorm(modelo$residuals, main = "Q-Q Plot de Residuos")
qqline(modelo$residuals, col = "red")
par(mfrow = c(1, 1)) # Volver a la configuración original
# Prueba de Shapiro-Wilk
shapiro_test <- shapiro.test(modelo$residuals)
print(shapiro_test)
##
## Shapiro-Wilk normality test
##
## data: modelo$residuals
## W = 0.78343, p-value < 2.2e-16
# Cargar el paquete lmtest
library(lmtest)
# Prueba de Breusch-Pagan
bp_test <- bptest(modelo)
print(bp_test)
##
## studentized Breusch-Pagan test
##
## data: modelo
## BP = 648.08, df = 7, p-value < 2.2e-16
Linealidad:
El gráfico de residuos vs. valores ajustados sugiere que la relación entre las variables independientes y la dependiente es aproximadamente lineal. Sin embargo, hay cierta variabilidad en los residuos, especialmente en los valores altos de los ajustados, lo que podría indicar que la linealidad no es perfecta. Independencia de los Errores:
El gráfico de residuos vs. orden no muestra un patrón claro, lo que sugiere que los errores son independientes entre sí, cumpliendo con este supuesto.
Normalidad de los Residuos: La prueba de Shapiro-Wilk arrojó un p-valor extremadamente bajo (< 2.2e-16), indicando que los residuos no siguen una distribución normal. Esto podría afectar la validez de las inferencias estadísticas basadas en el modelo.
Homoscedasticidad: La prueba de Breusch-Pagan mostró un p-valor muy bajo (< 2.2e-16), lo que indica la presencia significativa de heterocedasticidad. Esto significa que la variabilidad de los errores no es constante, lo que podría llevar a estimaciones ineficientes y errores estándar incorrectos
# 5. Predicción
###################################################################
# Crear un DataFrame con las características del apartamento
apartamento1 <- data.frame(areaconst = 300, estrato = factor(c(5, 6), levels = levels(data_apartamentos$estrato)), banios = 3, habitaciones = 5, parqueaderos = 3)
# Predecir el precio
predicciones <- predict(modelo, newdata = apartamento1)
# Mostrar las predicciones
print(predicciones)
## 1 2
## 640.4267 787.0287
Al comparar las dos predicciones, se observa que el apartamento ubicado en el estrato 6 tiene un precio predicho significativamente más alto (alrededor de 146.60 unidades más) que el apartamento en el estrato 5, manteniendo constantes las demás características (área construida de 300, 3 baños, 5 habitaciones, y 3 parqueaderos).
Esto confirma nuevamente la influencia significativa del estrato socioeconómico en el precio de las propiedades, con los precios incrementando a medida que se sube de estrato.
# 6. Sugerencias potenciales
###################################################################
# Filtrar y seleccionar las 5 ofertas más baratas
ofertas <- data %>%
filter(preciom <= 850,
areaconst >= 300, # Ajustar según el rango deseado
#parqueaderos == 3,
banios == 3,
#habitaciones == 5,
tipo == "Apartamento",
zona == "Zona Sur",
estrato %in% c(5, 6)) %>%
arrange(preciom) %>%
head(5)
# Crear el mapa
leaflet(ofertas) %>% addTiles() %>%
addCircleMarkers(~longitud, ~latitud, color = 'blue',
popup = ~paste("<br>Tipo:", tipo, "<br>Área:", areaconst, "<br>Parqueaderos:", parqueaderos, "<br>Baños:", banios, "<br>Habitaciones:", habitaciones, "<br>Estrato:", estrato, "<br>Zona:", zona, "<br>Precio:", preciom),
radius = 8, fillOpacity = 0.7) %>% setView(lng = mean(ofertas$longitud), lat = mean(ofertas$latitud), zoom = 12)
# Mostrando los resultados
print(ofertas %>% select(preciom, areaconst, parqueaderos, banios, habitaciones, estrato))
## # A tibble: 2 × 6
## preciom areaconst parqueaderos banios habitaciones estrato
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 299 932 1 3 3 5
## 2 850 352 4 3 3 6
Resultado:
ofertas <- data %>%
filter(preciom >= (min(predicciones) - 50) & preciom <= (max(predicciones) + 50),
## areaconst >= 300, # Ajustar según el rango deseado
## parqueaderos == 1,
banios >= 2, # Relajar este criterio
habitaciones >= 4, # Relajar este criterio
tipo == "Apartamento",
zona == "Zona Sur",
estrato %in% c(5, 6)) %>%
arrange(preciom) %>%
head(5)
# Crear el mapa
leaflet(ofertas) %>% addTiles() %>%
addCircleMarkers(~longitud, ~latitud, color = 'blue',
popup = ~paste("<br>Tipo:", tipo, "<br>Área:", areaconst, "<br>Parqueaderos:", parqueaderos, "<br>Baños:", banios, "<br>Habitaciones:", habitaciones, "<br>Estrato:", estrato, "<br>Zona:", zona, "<br>Precio:", preciom),
radius = 8, fillOpacity = 0.7) %>% setView(lng = mean(ofertas$longitud), lat = mean(ofertas$latitud), zoom = 12)
# Mostrando los resultados
print(ofertas %>% select(preciom, areaconst, parqueaderos, banios, habitaciones, estrato))
## # A tibble: 5 × 6
## preciom areaconst parqueaderos banios habitaciones estrato
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 594 133 2 5 4 6
## 2 595 146 2 4 4 6
## 3 595 128 2 5 4 6
## 4 600 204 2 4 4 5
## 5 600 200 2 5 4 6