Actividad 2

Caso C&A

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, Maria recibió una carta solicitando asesoria 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:

Caracteristicas Vivienda 1 Vivienda 2
Tipo Casa Apartamento
área construida 200 300
parqueaderos 1 3
baños 2 3
habitaciones 4 5
estrato 4 o 5 5 o 6
zona Norte Sur
crédito p-aprobado 350M 850M

Ayude a Maria a responder la solicitud, mediante técnicas modelación que usted conoce. Ella requiere le envíe un informe ejecutivo (no mas de dos paginas) donde analice los dos casos y sus recomendaciones. Como soporte del informe debe anexar las estimaciones, validaciones y comparación de modelos requeridos.

Pasos requeridos para la obtención de los resultados

1. Realice un filtro a la base de datos e incluya solo las ofertas de : base1: casas, de la zona norte de la ciudad. Presente los primeros 3 registros de las bases y algunas tablas que comprueben la consulta. (Adicional un mapa con los puntos de las bases. Discutir si todos los puntos se ubican en la zona correspondiente o se presentan valores en otras zonas, por que?).

library(paqueteMOD)
library(dplyr)
data(vivienda)
head(vivienda)
## # A tibble: 6 × 13
##      id zona   piso  estrato preciom areac…¹ parqu…² banios habit…³ tipo  barrio
##   <dbl> <fct>  <fct> <fct>     <dbl>   <dbl>   <dbl>  <dbl>   <dbl> <fct> <fct> 
## 1  1147 Zona … <NA>  3           250      70       1      3       6 Casa  20 de…
## 2  1169 Zona … <NA>  3           320     120       1      2       3 Casa  20 de…
## 3  1350 Zona … <NA>  3           350     220       2      2       4 Casa  20 de…
## 4  5992 Zona … 02    4           400     280       3      5       3 Casa  3 de …
## 5  1212 Zona … 01    5           260      90       1      2       3 Apar… acopi 
## 6  1724 Zona … 01    5           240      87       1      3       3 Apar… acopi 
## # … with 2 more variables: longitud <dbl>, latitud <dbl>, and abbreviated
## #   variable names ¹​areaconst, ²​parqueaderos, ³​habitaciones
# Base 1: casas de la zona norte de la ciudad
base_1 <- filter(vivienda, zona == "Zona Norte" & tipo == "Casa")
head(base_1, 3)
## # A tibble: 3 × 13
##      id zona   piso  estrato preciom areac…¹ parqu…² banios habit…³ tipo  barrio
##   <dbl> <fct>  <fct> <fct>     <dbl>   <dbl>   <dbl>  <dbl>   <dbl> <fct> <fct> 
## 1  1209 Zona … 02    5           320     150       2      4       6 Casa  acopi 
## 2  1592 Zona … 02    5           780     380       2      3       3 Casa  acopi 
## 3  4057 Zona … 02    6           750     445      NA      7       6 Casa  acopi 
## # … with 2 more variables: longitud <dbl>, latitud <dbl>, and abbreviated
## #   variable names ¹​areaconst, ²​parqueaderos, ³​habitaciones
# Base 2: casas de la zona centro de la ciudad
base_2 <- filter(vivienda, zona == "Zona Centro" & tipo == "Casa")
head(base_2, 3)
## # A tibble: 3 × 13
##      id zona   piso  estrato preciom areac…¹ parqu…² banios habit…³ tipo  barrio
##   <dbl> <fct>  <fct> <fct>     <dbl>   <dbl>   <dbl>  <dbl>   <dbl> <fct> <fct> 
## 1  5298 Zona … 01    3           650     240       2      4       4 Casa  alame…
## 2  5107 Zona … 02    4           400     460      NA      5       7 Casa  alame…
## 3  5117 Zona … 02    3           380     290      NA      4       8 Casa  alame…
## # … with 2 more variables: longitud <dbl>, latitud <dbl>, and abbreviated
## #   variable names ¹​areaconst, ²​parqueaderos, ³​habitaciones
# Base 3: casas de la zona oeste de la ciudad
base_3 <- filter(vivienda, zona == "Zona Oeste" & tipo == "Casa")
head(base_3, 3)
## # A tibble: 3 × 13
##      id zona   piso  estrato preciom areac…¹ parqu…² banios habit…³ tipo  barrio
##   <dbl> <fct>  <fct> <fct>     <dbl>   <dbl>   <dbl>  <dbl>   <dbl> <fct> <fct> 
## 1  6928 Zona … 03    6          1850     302       4      4       3 Casa  aguac…
## 2  7510 Zona … 03    6          1950     400       4      5       3 Casa  aguac…
## 3  7586 Zona … 03    6           870     275       3      5       4 Casa  aguac…
## # … with 2 more variables: longitud <dbl>, latitud <dbl>, and abbreviated
## #   variable names ¹​areaconst, ²​parqueaderos, ³​habitaciones
# Base 4: casas de la zona oriente de la ciudad
base_4 <- filter(vivienda, zona == "Zona Oriente" & tipo == "Casa")
head(base_4, 3)
## # A tibble: 3 × 13
##      id zona   piso  estrato preciom areac…¹ parqu…² banios habit…³ tipo  barrio
##   <dbl> <fct>  <fct> <fct>     <dbl>   <dbl>   <dbl>  <dbl>   <dbl> <fct> <fct> 
## 1  1147 Zona … <NA>  3           250      70       1      3       6 Casa  20 de…
## 2  1169 Zona … <NA>  3           320     120       1      2       3 Casa  20 de…
## 3  1350 Zona … <NA>  3           350     220       2      2       4 Casa  20 de…
## # … with 2 more variables: longitud <dbl>, latitud <dbl>, and abbreviated
## #   variable names ¹​areaconst, ²​parqueaderos, ³​habitaciones

Hasta esta parte se crean las bases por zona de tipo casa y se muestran los primeros 3 regitros como se solicita.

Ahora crearemos una columna llamada base donde agregaremos la base que corresponda a cada zona

vivienda$base <- ifelse(vivienda$zona =="Zona Norte" & vivienda$tipo =="Casa", "Base_1", 
                         ifelse(vivienda$zona =="Zona Centro" & vivienda$tipo =="Casa", "Base_2",
                          ifelse(vivienda$zona =="Zona Oeste" & vivienda$tipo =="Casa", "Base_3",
                           ifelse(vivienda$zona =="Zona Oriente" & vivienda$tipo =="Casa", "Base_4",
                            ifelse(vivienda$zona == "Zona Sur" & vivienda$tipo == "Casa", "Base_5", as.numeric("Otra"))))))

head(vivienda)
## # A tibble: 6 × 14
##      id zona   piso  estrato preciom areac…¹ parqu…² banios habit…³ tipo  barrio
##   <dbl> <fct>  <fct> <fct>     <dbl>   <dbl>   <dbl>  <dbl>   <dbl> <fct> <fct> 
## 1  1147 Zona … <NA>  3           250      70       1      3       6 Casa  20 de…
## 2  1169 Zona … <NA>  3           320     120       1      2       3 Casa  20 de…
## 3  1350 Zona … <NA>  3           350     220       2      2       4 Casa  20 de…
## 4  5992 Zona … 02    4           400     280       3      5       3 Casa  3 de …
## 5  1212 Zona … 01    5           260      90       1      2       3 Apar… acopi 
## 6  1724 Zona … 01    5           240      87       1      3       3 Apar… acopi 
## # … with 3 more variables: longitud <dbl>, latitud <dbl>, base <chr>, and
## #   abbreviated variable names ¹​areaconst, ²​parqueaderos, ³​habitaciones

Ahora procedemos a crear el mapa con cada zona:

library(raster)
library(sf)
library(tmap)
library(parzer)
library(rgdal)
library(leaflet)

cali=shapefile("C:/Users/Lenovo/ows/mc_barrios.shp")

cali.tmap = tm_shape(cali) +  tm_polygons()

vivienda_clean <- na.omit(vivienda[c("latitud", "longitud", "base")])

vivienda_clean$latitud = gsub(" ", "", paste("3.", substr(vivienda_clean$latitud, start = 2, stop = 5) ))
vivienda_clean$longitud = gsub(" ", "", paste("-76.", substr(vivienda_clean$longitud, start = 4, stop = 5) ))

vivienda_clean$base <- as.character(vivienda_clean$base)
vivienda_clean$latitud <- as.numeric(vivienda_clean$latitud)
vivienda_clean$longitud <- as.numeric(vivienda_clean$longitud)

vivienda_clean$base <- as.character(vivienda_clean$base)

colores <- colorFactor(palette = "Set1", domain = vivienda_clean$base)

mapa <- leaflet(vivienda_clean) %>%
  addTiles() %>%
  addCircleMarkers(lng = ~longitud, lat = ~latitud, color = ~colores(base), radius = 4)

mapa

2. Realice un análisis exploratorio de datos enfocado en la correlación entre la variable respuesta (precio del apartamento) en función del área construida, estrato, numero de baños, numero de habitaciones y zona donde se ubica la vivienda. Use gráficos interactivos con el paquete plotly e interprete los resultados.

library(heatmaply)
apply(X = is.na(vivienda), MARGIN = 2, FUN = sum)
##           id         zona         piso      estrato      preciom    areaconst 
##            3            3         2638            3            2            3 
## parqueaderos       banios habitaciones         tipo       barrio     longitud 
##         1605            3            3            3            3            3 
##      latitud         base 
##            3         5103

Despues de hacer este analisis se encuentra que la variable parqueaderos cuenta con 1605 valores nulos. Con respecto a las demas varibles en promedio se tienen un maximo de 3 valores nulos.

Analisis por variable

Precio

plot_ly(vivienda, x = ~preciom, type = "histogram")%>%
  layout(title = "Grafica distribución de precios")

En el histograma podemos observar que la mayoría de precios estan en el rango de 500M a 1000M.

Baños

plot_ly(vivienda, x = ~banios, type = "histogram")%>%
  layout(title = "Grafica distribución de baños")

En la grafica anterior podemos ver que la mayoría de ofertas tienen 2 a 4 baños, es interesante observar que hay viviendas que tienen 8 y hasta 10 baños, lo cual llama la atención revisar la descripción de estas viviendas, adicional se observa que hay viviendas que tienen 0 baños por lo cual procederemos a eliminarlos ya que no cumple con las condiciones de la asesoría planteada con anterioridad.

vivienda=vivienda[vivienda$banios!=0,]
summary(vivienda$banios)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##   1.000   2.000   3.000   3.128   4.000  10.000       3

Habitaciones

plot_ly(vivienda, x = ~habitaciones, type = "histogram")%>%
  layout(title = "Grafica distribución de habitaciones")

En la grafica anterior vemos viviendas con 0 habitaciones las cuales procederemos a eliminarlas, ya que no hace sentido tener una vivienda con 0 habitaciones.

vivienda=vivienda[vivienda$habitaciones!=0,]
summary(vivienda$habitaciones)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##   1.000   3.000   3.000   3.634   4.000  10.000       3

Area construida

summary(vivienda$areaconst)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##    30.0    80.0   125.0   350.2   236.0 47463.0       3
plot_ly(vivienda, x = ~areaconst, type = "histogram") %>%
  layout(title = "Grafica distribución de Area construida")

Si observamos la información anterior encontramos que el valor minimo es de 30 y un maximo 47463 y un promedio de 349.7.

Zona

plot_ly(vivienda, labels = ~zona, type = 'pie')  %>%
  layout(title = "Distribución de zona")

Observando la grafica de barras se aprecia que el 57% de las viviendas estan en la Zona Sur y el 23% en Norte.

Estrato

plot_ly(vivienda, labels = ~estrato, type = 'pie')  %>%
  layout(title = "Distribución de estrato")

Observando la grafica, se aprecia que el estrato 5 presenta la mayor concentración de viviendas, seguido de 6,4,3.

Preparación

En esta sección preparamos la data: 1. convertimos la variable estrato a numerica 2. Quitamos los valores nulos

vivienda$estrato=as.numeric(vivienda$estrato)
vivienda_new <- na.omit(vivienda[c("preciom","areaconst","estrato","banios","habitaciones", "parqueaderos")])

Correlación

library(GGally)
corr <-vivienda_new[,c("preciom","areaconst","estrato","banios","habitaciones", "parqueaderos")]
ggpairs(corr, title="Grafica de correlacion multiple") 

Luego de hacer el grafico de correlación, se especificaran cada uno de las relaciones que existen entre el Precio vs las otras variables predictoras.

Analisis de multicolinealidad

Luego de conocer la correlación entre varibles se puede decir que existe un posible problema de multicolinealidad entre la relación de (Baños y Habitaciones) y (Baños y Parquederos), ya que presentan una correlación positiva medianamente fuerte de 0.60 y 0.58 respectivamente, por lo cual se recomienda usar un metodo de selección de variables o excluir una de estas.

3. Estime un modelo de regresión lineal múltiple con las variables del punto anterior (precio = f(área construida, estrato, numero de cuartos, numero de parqueaderos, numero de baños ) ) e interprete los coeficientes si son estadísticamente significativos. Las interpretaciones deber están contextualizadas y discutir si los resultados son lógicos. Adicionalmente interprete el coeficiente R2 y discuta el ajuste del modelo e implicaciones (que podrían hacer para mejorarlo).

mod_multi = lm(preciom~areaconst+estrato+habitaciones+parqueaderos+banios, data = vivienda_new)
summary(mod_multi)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos + 
##     banios, data = vivienda_new)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -951.13 -103.72  -24.94   61.43 1183.29 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -2.763e+02  1.059e+01 -26.082  < 2e-16 ***
## areaconst     1.093e-03  1.350e-03   0.810    0.418    
## estrato       9.823e+01  3.143e+00  31.252  < 2e-16 ***
## habitaciones -1.044e+01  2.464e+00  -4.236  2.3e-05 ***
## parqueaderos  1.074e+02  2.703e+00  39.746  < 2e-16 ***
## banios        9.412e+01  2.817e+00  33.411  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 194.4 on 6682 degrees of freedom
## Multiple R-squared:  0.6638, Adjusted R-squared:  0.6635 
## F-statistic:  2639 on 5 and 6682 DF,  p-value: < 2.2e-16

Luego de estimar el modelo se observa que el r^2 es de 0.6638 lo cual nos indica que este modelo podría explicar el 66% de los casos de precios de viviendas, por otra parte tambien se identifica que la variable Area construida no representa un nivel de significancia dentro del modelo, lo cual concuerda con el analisis de regressión planteado en el punto anterio donde se encontró que entre la variable precio y el area construida solo había una correlación de 0.072.

Con respecto al R^2 ajustado da un poco menos que el R^2 esto indica que las variables de entradas adicionales no agregan valor al modelo.

Dado lo anterior se propone eliminar o seleccionar solo aquellas variables que presenten un nivel de significancia alta.

Propuesta

Se propone aplicar forward stepwise regression para estimar el modelo de manera gradual, partiendo de un modelo con solo el intercepto y en cada paso se incorpora una variable hasta cumplir con el criterio de parada.

# Se define un modelo Y=b0
mod_b0 = lm(preciom~1, data = vivienda_new)
# Se define un modelo con todas las predictoras
mod_all = lm(preciom~areaconst+estrato+habitaciones+parqueaderos+banios, data = vivienda_new)

# Se aplica el proceso de forward stepwise regression
forward <- step(mod_b0, direction='forward', scope=formula(mod_all), trace=0)

# Visualización de los resultados 
forward$anova
##             Step Df    Deviance Resid. Df Resid. Dev      AIC
## 1                NA          NA      6687  750809240 77774.02
## 2 + parqueaderos -1 357819325.3      6686  392989914 73446.43
## 3       + banios -1  88519891.3      6685  304470023 71741.58
## 4      + estrato -1  51348107.9      6684  253121915 70508.29
## 5 + habitaciones -1    671112.1      6683  252450803 70492.54
# resultado final del modelo
summary(forward)
## 
## Call:
## lm(formula = preciom ~ parqueaderos + banios + estrato + habitaciones, 
##     data = vivienda_new)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -951.17 -103.74  -24.73   61.46 1183.16 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -276.614     10.587 -26.126  < 2e-16 ***
## parqueaderos  107.424      2.703  39.742  < 2e-16 ***
## banios         94.183      2.816  33.446  < 2e-16 ***
## estrato        98.348      3.140  31.320  < 2e-16 ***
## habitaciones  -10.379      2.463  -4.215 2.53e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 194.4 on 6683 degrees of freedom
## Multiple R-squared:  0.6638, Adjusted R-squared:  0.6636 
## F-statistic:  3298 on 4 and 6683 DF,  p-value: < 2.2e-16

Luego de aplicar forward stepwise regression se tiene como resultado que: 1. Se elimina la variable area construida del modelo 2. El R^2 ajustado no mejora significativamente pasando de 0.6635 a 0.6636 3. El P-value se mantiene 4. El intercepto se mantiene igual

4. Realice la validación de supuestos del modelo e interprete los resultados (no es necesario corregir en caso de presentar problemas solo realizar sugerencias de que se podría hacer).

par(mfrow = c(2,2))
plot(mod_multi)

Verificación de supuestos sobre el error.

I. Los errores del modelo tienen media cero E[ε]=0

Si se observa la grafica 1 se observan que los errores tienen una media cero y tienen un comportamiento aleatorio.

II. Los errores del modelo tienen varianza constante V[ε]=σ2

Si observamos el grafico de residuales vs. valores ajustados se observa que existe una varianza constante, ya que no muestran ningun patron.

III. Los errores del modelo se distribuyen normal ε∼N(0,σ2)

Observando el grafico de normalidad vemos que la nube de puntos en la escala normal se puede agustar por una linea recta, por lo que se establece que los errores tiene una distribución normal.

IV. Los errores del modelo son independientes E[εi,εj]=0

library(lmtest)
dwtest(mod_multi,alternative ="two.sided",iterations = 1000)
## 
##  Durbin-Watson test
## 
## data:  mod_multi
## DW = 1.6178, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is not 0

Haciendo la prueba de Durbin Watson se obtiene que el modelo no cumple con la propiedad de independencia; basicamente si la constante de autocorrelación es igual a 0.

5. Con el modelo identificado debe predecir el precio de la vivienda con las características de la primera solicitud.

Para esta predicción tomaremos el modelo que tiene en cuenta la mayoría de variables de entrada de esta solicitud, como resultado obtenemos que para la primera solicitud el precio estimado es de 370.778.

predict(mod_multi,list(areaconst=200,parqueaderos=1,estrato=4,habitaciones=4, banios=2))
##       1 
## 370.778

6. Con las predicciones del modelo sugiera potenciales ofertas que responda a la solicitud de la vivienda 1. Tenga encuentra que la empresa tiene crédito preaprobado de máximo 350 millones de pesos. Realice un análisis y presente en un mapa al menos 5 ofertas potenciales que debe discutir.

Teniendo en cuenta las caracteristicas de la Vivienda 1 se hace un filtro de aspectos relevantes y se omiten algunas caracteristicas que no sean tan discriminatorias.

Ofertas <- filter(vivienda, zona == "Zona Norte" & 
                    tipo == "Casa" & parqueaderos == 1 & banios == 2 & habitaciones >= 4 & preciom <= 350)

Ofertas <- Ofertas[order(-Ofertas$areaconst),]
Ofertas <- head(Ofertas, 5)
head(Ofertas, 5)
## # A tibble: 5 × 14
##      id zona   piso  estrato preciom areac…¹ parqu…² banios habit…³ tipo  barrio
##   <dbl> <fct>  <fct>   <dbl>   <dbl>   <dbl>   <dbl>  <dbl>   <dbl> <fct> <fct> 
## 1  1943 Zona … <NA>        3     350     346       1      2       4 Casa  vipasa
## 2   309 Zona … <NA>        1     250     240       1      2       4 Casa  barra…
## 3   477 Zona … <NA>        1     240     240       1      2       4 Casa  urban…
## 4   725 Zona … <NA>        1     350     200       1      2       6 Casa  salom…
## 5   612 Zona … 01          1     270     196       1      2       4 Casa  calima
## # … with 3 more variables: longitud <dbl>, latitud <dbl>, base <chr>, and
## #   abbreviated variable names ¹​areaconst, ²​parqueaderos, ³​habitaciones
Ofertas <- na.omit(Ofertas[c("latitud", "longitud", "preciom")])

Ofertas$latitud = gsub(" ", "", paste("3.", substr(Ofertas$latitud, start = 2, stop = 5) ))
Ofertas$longitud = gsub(" ", "", paste("-76.", substr(Ofertas$longitud, start = 4, stop = 5) ))

Ofertas$preciom <- as.character(Ofertas$preciom)
Ofertas$latitud <- as.numeric(Ofertas$latitud)
Ofertas$longitud <- as.numeric(Ofertas$longitud)

Ofertas$preciom <- as.character(Ofertas$preciom)

colores <- colorFactor(palette = "Set1", domain = Ofertas$preciom)

mapa <- leaflet(Ofertas) %>%
  addTiles() %>%
  addCircleMarkers(lng = ~longitud, lat = ~latitud, color = ~colores(preciom), radius = 4)

mapa

7. Realice los pasos del 1 al 6. Para la segunda solicitud se tiene un crédito preaprobado por valor de $850 millones.

Primero vamos a predecir el precio de una vivienda con las caracteristicas del segundo caso.

predict(mod_multi,list(areaconst=300,parqueaderos=3,estrato=6,habitaciones=5, banios=3))
##        1 
## 865.9264

Tomando los valores maximos de la vivienda 2 obtuvimos una predicción de 865.9264.

Ahora mostraremos 5 ofertas donde se cumplan algunas condiciones relevantes y que estan disponibles en las ofertas.

Ofertas <- filter(vivienda, zona == "Zona Sur" & tipo == "Apartamento" & parqueaderos >= 3 & banios >= 3 &  habitaciones >= 4 & preciom <= 850)


Ofertas <- Ofertas[order(-Ofertas$areaconst),]
Ofertas <- head(Ofertas, 5)
head(Ofertas, 5)
## # A tibble: 5 × 14
##      id zona   piso  estrato preciom areac…¹ parqu…² banios habit…³ tipo  barrio
##   <dbl> <fct>  <fct>   <dbl>   <dbl>   <dbl>   <dbl>  <dbl>   <dbl> <fct> <fct> 
## 1  7182 Zona … <NA>        3     730     573       3      8       5 Apar… guada…
## 2  6868 Zona … 03          1     370     300       3      6       5 Apar… melen…
## 3  7512 Zona … <NA>        3     670     300       3      5       6 Apar… semin…
## 4  6175 Zona … 05          3     350     270       3      3       4 Apar… capri 
## 5  8036 Zona … <NA>        3     530     256       3      5       5 Apar… semin…
## # … with 3 more variables: longitud <dbl>, latitud <dbl>, base <chr>, and
## #   abbreviated variable names ¹​areaconst, ²​parqueaderos, ³​habitaciones
Ofertas <- na.omit(Ofertas[c("latitud", "longitud", "preciom")])

Ofertas$latitud = gsub(" ", "", paste("3.", substr(Ofertas$latitud, start = 2, stop = 5) ))
Ofertas$longitud = gsub(" ", "", paste("-76.", substr(Ofertas$longitud, start = 4, stop = 5) ))

Ofertas$preciom <- as.character(Ofertas$preciom)
Ofertas$latitud <- as.numeric(Ofertas$latitud)
Ofertas$longitud <- as.numeric(Ofertas$longitud)

Ofertas$preciom <- as.character(Ofertas$preciom)

colores <- colorFactor(palette = "Set1", domain = Ofertas$preciom)

mapa <- leaflet(Ofertas) %>%
  addTiles() %>%
  addCircleMarkers(lng = ~longitud, lat = ~latitud, color = ~colores(preciom), radius = 4)

mapa