María, gerente de la agencia inmobiliaria C&A, recibió una solicitud para asesorar la compra de dos viviendas para empleados de una compañía internacional. Para apoyar la decisión se utiliza una base de datos de ofertas inmobiliarias y se aplican técnicas de análisis exploratorio y modelación estadística.
El objetivo es analizar las características de las viviendas y estimar modelos que permitan comprender los factores que influyen en el precio de los inmuebles.
options(repos = c(CRAN = "https://cloud.r-project.org"))
install.packages("devtools")
## Installing package into 'C:/Users/David/AppData/Local/R/win-library/4.5'
## (as 'lib' is unspecified)
## package 'devtools' successfully unpacked and MD5 sums checked
##
## The downloaded binary packages are in
## C:\Users\David\AppData\Local\Temp\RtmpCwWC4X\downloaded_packages
library(devtools)
## Warning: package 'devtools' was built under R version 4.5.2
## Cargando paquete requerido: usethis
## Warning: package 'usethis' was built under R version 4.5.2
install.packages("devtools") # solo la primera vez
## Warning: package 'devtools' is in use and will not be installed
devtools::install_github("centromagis/paqueteMODELOS", force =TRUE)
## WARNING: Rtools is required to build R packages, but is not currently installed.
##
## Please download and install Rtools 4.5 from https://cran.r-project.org/bin/windows/Rtools/.
## Downloading GitHub repo centromagis/paqueteMODELOS@HEAD
## vctrs (0.6.5 -> 0.7.1 ) [CRAN]
## tibble (3.3.0 -> 3.3.1 ) [CRAN]
## rlang (1.1.6 -> 1.1.7 ) [CRAN]
## purrr (1.1.0 -> 1.2.1 ) [CRAN]
## magrittr (2.0.3 -> 2.0.4 ) [CRAN]
## dplyr (1.1.4 -> 1.2.0 ) [CRAN]
## digest (0.6.37 -> 0.6.39) [CRAN]
## curl (6.4.0 -> 7.0.0 ) [CRAN]
## xfun (0.52 -> 0.56 ) [CRAN]
## tidyr (1.3.1 -> 1.3.2 ) [CRAN]
## htmltools (0.5.8.1 -> 0.5.9 ) [CRAN]
## yaml (2.3.10 -> 2.3.12) [CRAN]
## Installing 12 packages: vctrs, tibble, rlang, purrr, magrittr, dplyr, digest, curl, xfun, tidyr, htmltools, yaml
## Installing packages into 'C:/Users/David/AppData/Local/R/win-library/4.5'
## (as 'lib' is unspecified)
## package 'vctrs' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'vctrs'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\David\AppData\Local\R\win-library\4.5\00LOCK\vctrs\libs\x64\vctrs.dll
## a C:\Users\David\AppData\Local\R\win-library\4.5\vctrs\libs\x64\vctrs.dll:
## Permission denied
## Warning: restored 'vctrs'
## package 'tibble' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'tibble'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\David\AppData\Local\R\win-library\4.5\00LOCK\tibble\libs\x64\tibble.dll
## a C:\Users\David\AppData\Local\R\win-library\4.5\tibble\libs\x64\tibble.dll:
## Permission denied
## Warning: restored 'tibble'
## package 'rlang' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'rlang'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\David\AppData\Local\R\win-library\4.5\00LOCK\rlang\libs\x64\rlang.dll
## a C:\Users\David\AppData\Local\R\win-library\4.5\rlang\libs\x64\rlang.dll:
## Permission denied
## Warning: restored 'rlang'
## package 'purrr' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'purrr'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\David\AppData\Local\R\win-library\4.5\00LOCK\purrr\libs\x64\purrr.dll
## a C:\Users\David\AppData\Local\R\win-library\4.5\purrr\libs\x64\purrr.dll:
## Permission denied
## Warning: restored 'purrr'
## package 'magrittr' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'magrittr'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\David\AppData\Local\R\win-library\4.5\00LOCK\magrittr\libs\x64\magrittr.dll
## a
## C:\Users\David\AppData\Local\R\win-library\4.5\magrittr\libs\x64\magrittr.dll:
## Permission denied
## Warning: restored 'magrittr'
## package 'dplyr' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'dplyr'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\David\AppData\Local\R\win-library\4.5\00LOCK\dplyr\libs\x64\dplyr.dll
## a C:\Users\David\AppData\Local\R\win-library\4.5\dplyr\libs\x64\dplyr.dll:
## Permission denied
## Warning: restored 'dplyr'
## package 'digest' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'digest'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\David\AppData\Local\R\win-library\4.5\00LOCK\digest\libs\x64\digest.dll
## a C:\Users\David\AppData\Local\R\win-library\4.5\digest\libs\x64\digest.dll:
## Permission denied
## Warning: restored 'digest'
## package 'curl' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'curl'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\David\AppData\Local\R\win-library\4.5\00LOCK\curl\libs\x64\curl.dll a
## C:\Users\David\AppData\Local\R\win-library\4.5\curl\libs\x64\curl.dll:
## Permission denied
## Warning: restored 'curl'
## package 'xfun' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'xfun'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\David\AppData\Local\R\win-library\4.5\00LOCK\xfun\libs\x64\xfun.dll a
## C:\Users\David\AppData\Local\R\win-library\4.5\xfun\libs\x64\xfun.dll:
## Permission denied
## Warning: restored 'xfun'
## package 'tidyr' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'tidyr'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\David\AppData\Local\R\win-library\4.5\00LOCK\tidyr\libs\x64\tidyr.dll
## a C:\Users\David\AppData\Local\R\win-library\4.5\tidyr\libs\x64\tidyr.dll:
## Permission denied
## Warning: restored 'tidyr'
## package 'htmltools' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'htmltools'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\David\AppData\Local\R\win-library\4.5\00LOCK\htmltools\libs\x64\htmltools.dll
## a
## C:\Users\David\AppData\Local\R\win-library\4.5\htmltools\libs\x64\htmltools.dll:
## Permission denied
## Warning: restored 'htmltools'
## package 'yaml' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'yaml'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\David\AppData\Local\R\win-library\4.5\00LOCK\yaml\libs\x64\yaml.dll a
## C:\Users\David\AppData\Local\R\win-library\4.5\yaml\libs\x64\yaml.dll:
## Permission denied
## Warning: restored 'yaml'
##
## The downloaded binary packages are in
## C:\Users\David\AppData\Local\Temp\RtmpCwWC4X\downloaded_packages
## ── R CMD build ─────────────────────────────────────────────────────────────────
## WARNING: Rtools is required to build R packages, but is not currently installed.
##
## Please download and install Rtools 4.5 from https://cran.r-project.org/bin/windows/Rtools/.
## checking for file 'C:\Users\David\AppData\Local\Temp\RtmpCwWC4X\remotes71f063c049ef\Centromagis-paqueteMODELOS-3b06257/DESCRIPTION' ... ✔ checking for file 'C:\Users\David\AppData\Local\Temp\RtmpCwWC4X\remotes71f063c049ef\Centromagis-paqueteMODELOS-3b06257/DESCRIPTION' (881ms)
## ─ preparing 'paqueteMODELOS': (13s)
## ✔ checking DESCRIPTION meta-information
## ─ checking for LF line-endings in source and make files and shell scripts (719ms)
## ─ checking for empty or unneeded directories
## ─ building 'paqueteMODELOS_0.1.0.tar.gz' (361ms)
##
##
## Installing package into 'C:/Users/David/AppData/Local/R/win-library/4.5'
## (as 'lib' is unspecified)
library(paqueteMODELOS)
## Cargando paquete requerido: boot
## Cargando paquete requerido: broom
## Warning: package 'broom' was built under R version 4.5.2
## Cargando paquete requerido: GGally
## Warning: package 'GGally' was built under R version 4.5.2
## Cargando paquete requerido: ggplot2
## Warning: package 'ggplot2' was built under R version 4.5.2
## Cargando paquete requerido: gridExtra
## Cargando paquete requerido: knitr
## Warning: package 'knitr' was built under R version 4.5.2
## Cargando paquete requerido: summarytools
## Warning: package 'summarytools' was built under R version 4.5.2
library(dplyr)
##
## Adjuntando el paquete: 'dplyr'
## The following object is masked from 'package:gridExtra':
##
## combine
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
data("vivienda")
Se construye la primera base, en donde se encuentran las casas ubicadas en la zona norte.
# Visualización de información relevante de la base original.
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>
str(vivienda)
## spc_tbl_ [8,322 × 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ id : num [1:8322] 1147 1169 1350 5992 1212 ...
## $ zona : chr [1:8322] "Zona Oriente" "Zona Oriente" "Zona Oriente" "Zona Sur" ...
## $ piso : chr [1:8322] NA NA NA "02" ...
## $ estrato : num [1:8322] 3 3 3 4 5 5 4 5 5 5 ...
## $ preciom : num [1:8322] 250 320 350 400 260 240 220 310 320 780 ...
## $ areaconst : num [1:8322] 70 120 220 280 90 87 52 137 150 380 ...
## $ parqueaderos: num [1:8322] 1 1 2 3 1 1 2 2 2 2 ...
## $ banios : num [1:8322] 3 2 2 5 2 3 2 3 4 3 ...
## $ habitaciones: num [1:8322] 6 3 4 3 3 3 3 4 6 3 ...
## $ tipo : chr [1:8322] "Casa" "Casa" "Casa" "Casa" ...
## $ barrio : chr [1:8322] "20 de julio" "20 de julio" "20 de julio" "3 de julio" ...
## $ longitud : num [1:8322] -76.5 -76.5 -76.5 -76.5 -76.5 ...
## $ latitud : num [1:8322] 3.43 3.43 3.44 3.44 3.46 ...
## - 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_character" "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"
## .. ..$ parqueaderos: list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ banios : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ habitaciones: 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>
summary(vivienda)
## id zona piso estrato
## Min. : 1 Length:8322 Length:8322 Min. :3.000
## 1st Qu.:2080 Class :character Class :character 1st Qu.:4.000
## Median :4160 Mode :character Mode :character Median :5.000
## Mean :4160 Mean :4.634
## 3rd Qu.:6240 3rd Qu.:5.000
## Max. :8319 Max. :6.000
## NA's :3 NA's :3
## preciom areaconst parqueaderos banios
## Min. : 58.0 Min. : 30.0 Min. : 1.000 Min. : 0.000
## 1st Qu.: 220.0 1st Qu.: 80.0 1st Qu.: 1.000 1st Qu.: 2.000
## Median : 330.0 Median : 123.0 Median : 2.000 Median : 3.000
## Mean : 433.9 Mean : 174.9 Mean : 1.835 Mean : 3.111
## 3rd Qu.: 540.0 3rd Qu.: 229.0 3rd Qu.: 2.000 3rd Qu.: 4.000
## Max. :1999.0 Max. :1745.0 Max. :10.000 Max. :10.000
## NA's :2 NA's :3 NA's :1605 NA's :3
## habitaciones tipo barrio longitud
## Min. : 0.000 Length:8322 Length:8322 Min. :-76.59
## 1st Qu.: 3.000 Class :character Class :character 1st Qu.:-76.54
## Median : 3.000 Mode :character Mode :character Median :-76.53
## Mean : 3.605 Mean :-76.53
## 3rd Qu.: 4.000 3rd Qu.:-76.52
## Max. :10.000 Max. :-76.46
## NA's :3 NA's :3
## latitud
## Min. :3.333
## 1st Qu.:3.381
## Median :3.416
## Mean :3.418
## 3rd Qu.:3.452
## Max. :3.498
## NA's :3
dim(vivienda)
## [1] 8322 13
tail(vivienda)
## # A tibble: 6 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 6417 Zona S… <NA> 6 1800 400 3 6 5
## 2 6998 Zona S… <NA> 6 1000 189 3 5 4
## 3 8139 Zona S… <NA> 5 530 142 2 4 4
## 4 NA <NA> <NA> NA NA NA NA NA NA
## 5 NA <NA> <NA> NA NA NA NA NA NA
## 6 NA <NA> <NA> NA 330 NA NA NA NA
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
names(vivienda)
## [1] "id" "zona" "piso" "estrato" "preciom"
## [6] "areaconst" "parqueaderos" "banios" "habitaciones" "tipo"
## [11] "barrio" "longitud" "latitud"
#Información en el campo "tipo"
vivienda %>%
distinct(tipo)
## # A tibble: 3 × 1
## tipo
## <chr>
## 1 Casa
## 2 Apartamento
## 3 <NA>
#Información en el campo "zona"
vivienda %>%
distinct(zona)
## # A tibble: 6 × 1
## zona
## <chr>
## 1 Zona Oriente
## 2 Zona Sur
## 3 Zona Norte
## 4 Zona Oeste
## 5 Zona Centro
## 6 <NA>
#Construcción de la base1 con los filtros requeridos
base1 <- vivienda %>%
filter(tipo == "Casa",
zona == "Zona Norte")
Se presentan los primeros 3 registros de la base y algunas tablas para validar el resultado.
#Visualización de los primeros 3 campos
head(base1,3)
## # A tibble: 3 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1209 Zona N… 02 5 320 150 2 4 6
## 2 1592 Zona N… 02 5 780 380 2 3 3
## 3 4057 Zona N… 02 6 750 445 NA 7 6
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
#Tamaño de la base creada
dim(base1)
## [1] 722 13
#Se vizualiza la información que tiene cada campo
table(base1$tipo)
##
## Casa
## 722
table(base1$zona)
##
## Zona Norte
## 722
#Se realiza tabla para validar cuantas casas hay por cada tipo de zona
table(base1$tipo, base1$zona)
##
## Zona Norte
## Casa 722
#Tablas para analisar el resultado obtenido
head(base1)
## # A tibble: 6 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1209 Zona N… 02 5 320 150 2 4 6
## 2 1592 Zona N… 02 5 780 380 2 3 3
## 3 4057 Zona N… 02 6 750 445 NA 7 6
## 4 4460 Zona N… 02 4 625 355 3 5 5
## 5 6081 Zona N… 02 5 750 237 2 6 6
## 6 7824 Zona N… 02 4 600 160 1 4 5
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
str(base1)
## spc_tbl_ [722 × 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ id : num [1:722] 1209 1592 4057 4460 6081 ...
## $ zona : chr [1:722] "Zona Norte" "Zona Norte" "Zona Norte" "Zona Norte" ...
## $ piso : chr [1:722] "02" "02" "02" "02" ...
## $ estrato : num [1:722] 5 5 6 4 5 4 5 5 3 3 ...
## $ preciom : num [1:722] 320 780 750 625 750 600 420 490 230 190 ...
## $ areaconst : num [1:722] 150 380 445 355 237 160 200 118 160 435 ...
## $ parqueaderos: num [1:722] 2 2 NA 3 2 1 4 2 NA NA ...
## $ banios : num [1:722] 4 3 7 5 6 4 4 4 2 0 ...
## $ habitaciones: num [1:722] 6 3 6 5 6 5 5 4 3 0 ...
## $ tipo : chr [1:722] "Casa" "Casa" "Casa" "Casa" ...
## $ barrio : chr [1:722] "acopi" "acopi" "acopi" "acopi" ...
## $ longitud : num [1:722] -76.5 -76.5 -76.5 -76.5 -76.5 ...
## $ latitud : num [1:722] 3.48 3.49 3.39 3.41 3.37 ...
## - 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_character" "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"
## .. ..$ parqueaderos: list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ banios : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ habitaciones: 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>
summary(base1)
## id zona piso estrato
## Min. : 58.0 Length:722 Length:722 Min. :3.000
## 1st Qu.: 766.2 Class :character Class :character 1st Qu.:3.000
## Median :2257.0 Mode :character Mode :character Median :4.000
## Mean :2574.6 Mean :4.202
## 3rd Qu.:4225.0 3rd Qu.:5.000
## Max. :8319.0 Max. :6.000
##
## preciom areaconst parqueaderos banios
## Min. : 89.0 Min. : 30.0 Min. : 1.000 Min. : 0.000
## 1st Qu.: 261.2 1st Qu.: 140.0 1st Qu.: 1.000 1st Qu.: 2.000
## Median : 390.0 Median : 240.0 Median : 2.000 Median : 3.000
## Mean : 445.9 Mean : 264.9 Mean : 2.182 Mean : 3.555
## 3rd Qu.: 550.0 3rd Qu.: 336.8 3rd Qu.: 3.000 3rd Qu.: 4.000
## Max. :1940.0 Max. :1440.0 Max. :10.000 Max. :10.000
## NA's :287
## habitaciones tipo barrio longitud
## Min. : 0.000 Length:722 Length:722 Min. :-76.59
## 1st Qu.: 3.000 Class :character Class :character 1st Qu.:-76.53
## Median : 4.000 Mode :character Mode :character Median :-76.52
## Mean : 4.507 Mean :-76.52
## 3rd Qu.: 5.000 3rd Qu.:-76.50
## Max. :10.000 Max. :-76.47
##
## latitud
## Min. :3.333
## 1st Qu.:3.452
## Median :3.468
## Mean :3.460
## 3rd Qu.:3.482
## Max. :3.496
##
A continuación se muestra en el mapa, donde se encuentran ubicadas las casas de la zona norte.
library(ggplot2)
ggplot(base1, aes(x = longitud, y = latitud)) +
geom_point(color = "blue", alpha = 0.6) +
labs(title = "Ubicación de casas en la zona norte",
x = "Longitud",
y = "Latitud") +
theme_minimal()
Para validar la información anterior, y corroborar si todos los puntos se encuentran en la zona correspondiente, se realiza una visualización de todos los registros de la base original.
library(dplyr)
vivienda_mapa <- vivienda %>%
mutate(grupo = ifelse(tipo == "Casa" & zona == "Zona Norte",
"Casas Zona Norte",
"Otras viviendas"))
table(vivienda_mapa$grupo)
##
## Casas Zona Norte Otras viviendas
## 722 7597
ggplot(vivienda_mapa, aes(x = longitud, y = latitud, color = grupo)) +
geom_point(alpha = 0.6) +
scale_color_manual(values = c("red", "lightgrey")) +
labs(title = "Distribución geográfica de viviendas",
subtitle = "Casas en zona norte vs resto de viviendas",
x = "Longitud",
y = "Latitud",
color = "Grupo") +
theme_minimal()
## Warning: Removed 3 rows containing missing values or values outside the scale range
## (`geom_point()`).
No todos los puntos se ubican en la zona correspondiente, presentan valores en otras zonas. Las casas que tienen la clasificación Zona Norte, que están fuera de esta área en el mapa puede deberse a inconsistencias en la base de datos. Es posible que algunas viviendas estén mal clasificadas en la variable zona, o que existan errores en las coordenadas latitud y longitud utilizadas para georreferenciarlas, también que la variable zona represente una clasificación categórica, mientras que el mapa se basa en coordenadas geográficas, por lo que si los límites espaciales de la zona norte no están definidos explícitamente en el análisis, algunos puntos pueden aparecer fuera de la ubicación esperada.
Se realiza un análisis enfocado en identificar la relación que tienen los precios de las casas frente a el área construida, el estrato, el numero de baños, el numero de habitaciones y la zona donde se ubica la vivienda.
# Análisis exploratorio
#install.packages("plotly")
library(plotly)
## Warning: package 'plotly' was built under R version 4.5.2
##
## Adjuntando el paquete: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
#Relación entre área construida y precio
plot_ly(base1,
x = ~areaconst,
y = ~preciom,
type = "scatter",
mode = "markers",
marker = list(color = "steelblue")) %>%
layout(title = "Relación entre área construida y precio",
xaxis = list(title = "Área construida",
zeroline = FALSE),
yaxis = list(title = "Precio (millones)",
zeroline = FALSE),
shapes = list(
# Línea vertical área = 200
list(type = "line",
x0 = 200, x1 = 200,
y0 = min(base1$preciom),
y1 = max(base1$preciom),
line = list(color = "red", dash = "dash")),
# Línea horizontal precio = 350
list(type = "line",
x0 = min(base1$areaconst),
x1 = max(base1$areaconst),
y0 = 350, y1 = 350,
line = list(color = "red", dash = "dash"))
),
annotations = list(
list(x = 200,
y = 350,
showarrow = TRUE,
arrowhead = 2)
))
Este gráfico permite ver que hay una gran concentración de viviendas en el punto y alrededor de donde se encuentra visualmente las casas que cuestan 350 millones y miden 200 metros.
#Precio de la vivienda según estrato
plot_ly(base1,
x = ~factor(estrato),
y = ~preciom,
type = "box") %>%
layout(title = "Precio de la vivienda según estrato",
xaxis = list(title = "Estrato"),
yaxis = list(title = "Precio (millones)"))
Vemos que hay mayor concentración de viviendas en el estrato 4 con el precio de 350 millones, que en el estrato 5.
#Relación entre número de baños y precio
plot_ly(base1,
x = ~banios,
y = ~preciom,
type = "scatter",
mode = "markers") %>%
layout(title = "Relación entre número de baños y precio",
xaxis = list(title = "Número de baños"),
yaxis = list(title = "Precio"))
Observamos que hay casas que cumplen la condición de tener 2 baños y costar 350 millones.
# Relación entre número de habitaciones y precio
plot_ly(base1,
x = ~habitaciones,
y = ~preciom,
type = "scatter",
mode = "markers") %>%
layout(title = "Relación entre número de habitaciones y precio",
xaxis = list(title = "Habitaciones"),
yaxis = list(title = "Precio"))
Las habitaciones también satisfacen la condición de tener 4 en las casas que cuestan 350 millones.
#Precio de viviendas según zona
plot_ly(vivienda,
x = ~zona,
y = ~preciom,
type = "box") %>%
layout(title = "Precio de viviendas según zona",
xaxis = list(title = "Zona"),
yaxis = list(title = "Precio"))
## Warning: Ignoring 3 observations
Utilizando toda la base, se puede evidenciar que la zona norte concentra una gran cantidad de casas que cuestan 350 millones
# Resumen de la información
plot_ly(base1,
x = ~areaconst,
y = ~preciom,
type = "scatter",
mode = "markers",
color = ~factor(estrato),
size = ~banios,
sizes = c(10,40),
text = ~paste("Habitaciones:", habitaciones,
"<br>Baños:", banios,
"<br>Estrato:", estrato),
hoverinfo = "text") %>%
layout(title = "Relación entre área, precio y características de la vivienda",
xaxis = list(title = "Área construida"),
yaxis = list(title = "Precio (millones)"))
## Warning: `line.width` does not currently support multiple values.
## Warning: `line.width` does not currently support multiple values.
## Warning: `line.width` does not currently support multiple values.
## Warning: `line.width` does not currently support multiple values.
Con este resumen se puede observar con mayor facilidad la cantidad de casas que satisfacen la necesidad del comprador.
Construcción del modelo de regresión lineal múltiple.
modelo1 <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios,
data = base1)
summary(modelo1)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = base1)
##
## Residuals:
## Min 1Q Median 3Q Max
## -784.29 -77.56 -16.03 47.67 978.61
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -238.17090 44.40551 -5.364 1.34e-07 ***
## areaconst 0.67673 0.05281 12.814 < 2e-16 ***
## estrato 80.63495 9.82632 8.206 2.70e-15 ***
## habitaciones 7.64511 5.65873 1.351 0.177
## parqueaderos 24.00598 5.86889 4.090 5.14e-05 ***
## banios 18.89938 7.48800 2.524 0.012 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 155.1 on 429 degrees of freedom
## (287 observations deleted due to missingness)
## Multiple R-squared: 0.6041, Adjusted R-squared: 0.5995
## F-statistic: 130.9 on 5 and 429 DF, p-value: < 2.2e-16
Interpretación de los coeficientes:
Con este modelo se busca explicar el precio de las viviendas que satisfacen el área construida, el estrato socioeconómico, el número de habitaciones, el número de parqueaderos y el número de baños.
Área construida:
El coeficiente del área construida es de 0.6767, lo cual es estadísticamente significativo (p < 0.001). Manteniendo constantes las demás variables del modelo, un aumento de un metro cuadrado en el área construida incrementa en promedio el precio de la vivienda en aproximadamente 0.68 millones de pesos. Este resultado nos permite observar un comportamiento esperado del mercado inmobiliario, ya que viviendas con mayor área construida tienden a tener mayor valor.
Estrato socioeconómico:
El coeficiente estimado para el estrato es 80.63 lo cual muestra que también significativo (p < 0.001). Esto mantiene constantes las demás variables, un aumento de una unidad en el estrato socioeconómico incrementa en promedio el precio de la vivienda en aproximadamente 80.63 millones de pesos. Este resultado es lógico, ya que las viviendas ubicadas en los estratos más altos, pueden estar localizadas en zonas con mejores condiciones urbanas, infraestructura y servicios, esto incrementa su valor en el mercado.
Número de habitaciones;
El coeficiente asociado al número de habitaciones es 7.65, pero no es estadísticamente significativo (p = 0.177). Esto indica que, manteniendo constantes las demás variables, no existe evidencia estadística suficiente para afirmar que el número de habitaciones tenga un efecto significativo sobre el precio de la vivienda en este modelo. Una posible explicación es que el efecto de las habitaciones ya esté parcialmente capturado por otras variables como el área construida, ya que viviendas más grandes tienden a tener más habitaciones.
Número de parqueaderos:
El coeficiente asociado a los parqueaderos es 24.01 y es estadísticamente significativo (p < 0.001), manteniendo constantes las demás variables, cada parqueadero adicional incrementa en promedio el precio de la vivienda en aproximadamente 24 millones de pesos. Este resultado es coherente con la lógica del mercado inmobiliario urbano, donde la disponibilidad de estacionamiento representa una característica altamente valorada por los compradores.
Número de baños:
El coeficiente estimado para el número de baños es 18.90 y es estadísticamente significativo (p = 0.012). Permite tener constancia en las demás variables, cada baño adicional incrementa el precio promedio de la vivienda en aproximadamente 18.9 millones de pesos. Este resultado es consistente con el mercado inmobiliario, ya que viviendas con mayor número de baños suelen ofrecer mayor comodidad y funcionalidad.
R-squared:
Interpretación: El modelo presenta un R² de 0.6041. Esto indica que aproximadamente el 60.41% de la variabilidad en el precio de las viviendas es explicada por las variables incluidas en el modelo: área construida, estrato, número de habitaciones, número de parqueaderos y número de baños. El R² ajustado es 0.5995, lo que indica que el modelo mantiene una capacidad explicativa similar incluso después de ajustar por el número de variables incluidas.
Ajuste del modelo:
El valor R² indica un nivel de ajuste de moderado a alto, ya que el modelo explica aproximadamente el 60% de la variación en los precios de la vivienda. Sin embargo, aproximadamente el 40% de la variación en el precio permanece sin explicar por el modelo, lo que sugiere que existen otros factores importantes que influyen en el valor de los inmuebles y que no están incluidos en el modelo actual. En general, los resultados del modelo son consistentes con la lógica del mercado inmobiliario, según la cual variables como la superficie construida, el nivel socioeconómico, el número de baños y la disponibilidad de aparcamiento influyen significativamente en los precios de la vivienda.
Implicaciones:
Los resultados del modelo sugieren que la superficie construida y el nivel socioeconómico son los factores más influyentes en la determinación de los precios de la vivienda en la muestra analizada. Esto sugiere que estas variables deben considerarse determinantes clave del valor de los inmuebles al recomendar la compra de una vivienda. Además, características como el número de baños y la disponibilidad de plazas de aparcamiento también influyen significativamente en el valor de mercado de la vivienda.
Posibles mejoras del modelo:
El modelo podría mejorarse mediante la incorporación de otras variables relevantes que influyen en el precio de las viviendas, tales como:
Asimismo, podrían explorarse modelos no lineales o interacciones entre variables, con el fin de capturar de manera más precisa las relaciones existentes entre las características del inmueble y su precio en el mercado.
Validación de supuestos.
# Gráficos de diagnóstico del modelo
par(mfrow=c(2,2))
plot(modelo1)
Linealidad (Residuals vs Fitted)
Gráfico: Residuals vs Fitted
Interpretación: El gráfico de residuos vs. valores ajustados permite evaluar si la relación entre las variables explicativas y la variable de respuesta es aproximadamente lineal. En un modelo bien ajustado, los residuos se distribuyen aleatoriamente alrededor de cero. En este gráfico, los residuos se encuentran horizontalmente alrededor de cero, pero la varianza tiende a aumentar ligeramente a medida que aumenta el valor ajustado. Esto sugiere que la relación no es completamente lineal o que podría haber heterogeneidad en la variabilidad de los residuos. Sin embargo, no se observaron curvas pronunciadas, lo que indica una grave violación del supuesto de linealidad.
Sugerencias. Para mejorar el ajuste del modelo, considere lo siguiente:
Gráfico: Normal Q-Q
Interpretación: El gráfico Q-Q compara la distribución de los residuos con una distribución normal teórica. Si los puntos siguen aproximadamente la diagonal, se considera que el supuesto de normalidad se cumple en cierta medida. Muestra que los puntos siguen la diagonal en el centro, pero se desvían ligeramente en las colas, especialmente en los valores extremos. Esto indica que los residuos no se distribuyen con normalidad perfecta, posiblemente debido a valores atípicos o colas más pesadas que la distribución normal.
Sugerencias. Para mejorar esta suposición, considere lo siguiente: - Aplicar una transformación a la variable de respuesta (p. ej., transformación logarítmica del precio). - Usar un modelo robusto.
Gráfico: Scale-Location
Interpretación: Este gráfico permite evaluar si la varianza de los residuos es constante en todos los valores ajustados. En este caso, se observa una tendencia creciente en la varianza de los puntos, lo que indica que la variabilidad de los residuos aumenta a medida que aumentan los valores ajustados. Este patrón sugiere heterocedasticidad; es decir, la varianza de los errores no es constante.
Sugerencias. Si existe heterocedasticidad, considere lo siguiente:
Gráfico: Residuals vs Leverage
Interpretación: Este gráfico ayuda a identificar observaciones con alto apalancamiento o influencia en el modelo. La línea punteada representa la distancia de Cook, que es útil para identificar puntos potencialmente influyentes. El gráfico muestra algunas observaciones con alto apalancamiento, especialmente cerca del extremo derecho. Sin embargo, la mayoría de los puntos se encuentran dentro de la curva de distancia de Cook, lo que sugiere que ninguna observación tiene una gran influencia en el ajuste del modelo. No obstante, algunos casos requieren mayor investigación.
Sugerencias. Una vez identificadas las observaciones potencialmente influyentes, se recomienda: - Revisar los datos en busca de errores. - Evaluar el impacto de estas observaciones en el modelo. - Considerar métodos de regresión robusta.
# Multicolinealidad
library(car)
## Cargando paquete requerido: carData
##
## Adjuntando el paquete: 'car'
## The following object is masked from 'package:dplyr':
##
## recode
## The following object is masked from 'package:boot':
##
## logit
vif(modelo1)
## areaconst estrato habitaciones parqueaderos banios
## 1.460998 1.307757 1.721015 1.226334 1.967421
Interpretación:
El factor de inflación de la varianza (VIF) fue calculado para evaluar la presencia de multicolinealidad entre las variables explicativas del modelo. Los resultados muestran valores de VIF entre 1.22 y 1.97, los cuales se encuentran muy por debajo del umbral comúnmente utilizado de 5.
Esto indica que no existe evidencia de problemas de multicolinealidad significativa entre las variables explicativas, por lo que cada variable aporta información diferente al modelo y los coeficientes estimados pueden considerarse estables y confiables.
Precio de la vivienda con las características.
# Datos de la vivienda a evaluar
nueva_vivienda <- data.frame(
areaconst = c(200,200),
estrato = c(4,5),
habitaciones = c(4,4),
parqueaderos = c(1,1),
banios = c(2,2)
)
nueva_vivienda
## areaconst estrato habitaciones parqueaderos banios
## 1 200 4 4 1 2
## 2 200 5 4 1 2
# Prediccion del precio con el modelo
prediccion <- predict(modelo1, newdata = nueva_vivienda)
prediccion
## 1 2
## 312.1010 392.7359
resultado_pred <- cbind(nueva_vivienda, precio_estimado = prediccion)
resultado_pred
## areaconst estrato habitaciones parqueaderos banios precio_estimado
## 1 200 4 4 1 2 312.1010
## 2 200 5 4 1 2 392.7359
# viviendas con las características de la solicitud
ofertas <- base1 %>%
filter(
estrato %in% c(4,5),
parqueaderos >= 1,
banios >= 2,
habitaciones >= 4,
between(areaconst,150,250)
)
# Predecir precios con el modelo
ofertas$precio_estimado <- predict(modelo1, newdata = ofertas)
# Viviendas que cumplen el presupuesto
ofertas_potenciales <- ofertas %>%
filter(precio_estimado <= 350)
# Top 5
ofertas_final <- ofertas_potenciales %>%
head(5)
ofertas_final
## # A tibble: 5 × 14
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 7824 Zona N… 02 4 600 160 1 4 5
## 2 464 Zona N… 02 4 330 165 1 4 4
## 3 4471 Zona N… 02 4 340 162 1 4 4
## 4 1222 Zona N… 02 4 360 216 2 2 4
## 5 5258 Zona N… <NA> 4 370 192 2 3 4
## # ℹ 5 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>,
## # precio_estimado <dbl>
View(ofertas_final)
# Mapa
library(plotly)
plot_ly(ofertas_final,
x = ~longitud,
y = ~latitud,
type = "scatter",
mode = "markers",
marker = list(size = 12,
color = "red"),
text = ~paste(
"Precio estimado:", round(precio_estimado,1), "millones",
"<br>Área:", areaconst,
"<br>Estrato:", estrato,
"<br>Baños:", banios,
"<br>Habitaciones:", habitaciones
),
hoverinfo = "text") %>%
layout(title = "Ofertas potenciales de vivienda (Zona Norte)",
xaxis = list(title = "Longitud"),
yaxis = list(title = "Latitud"))
Identificación de Propiedades Potenciales
Con base en el modelo de regresión estimado previamente, identificamos propiedades con características similares a las requeridas para nuestra primera vivienda: ubicadas en la zona norte de la ciudad, con un nivel socioeconómico de 4 o superior, con al menos dos baños, cuatro recámaras y estacionamiento seguro. Posteriormente, utilizamos el modelo para estimar los precios esperados de estas propiedades y excluimos aquellas cuyos precios esperados no excedían nuestro presupuesto máximo de 350 millones de pesos. Esto resultó en una lista corta de cinco propiedades potenciales que cumplían con nuestros requisitos. Las propiedades seleccionadas se ubican en la zona norte de la ciudad, en las zonas de Acopí, El Bosque y La Merced. La superficie construida oscila entre 160 y 216 metros cuadrados, lo cual se acerca relativamente a nuestro requerimiento inicial de aproximadamente 200 metros cuadrados. Los precios esperados oscilan entre 324 y 349 millones de pesos, todos dentro de nuestro presupuesto.
Análisis de la propiedad
Las viviendas en El Bosque tienen los precios proyectados más bajos (entre 324 y 326 millones de euros), lo que las convierte en una opción atractiva desde una perspectiva económica. Además, ofrecen un número razonable de dormitorios y baños. Por otro lado, las viviendas en La Merced ofrecen una superficie cercana a la necesidad inicial de 200 m² y dos plazas de aparcamiento, lo que puede ser una ventaja adicional para los compradores. Las viviendas en Acopi ofrecen cinco dormitorios y cuatro baños, lo que las hace especialmente adecuadas para familias numerosas.
Recomendaciones
Teniendo en cuenta sus necesidades y presupuesto, considere las viviendas en La Merced, que se ajustan mejor a sus necesidades iniciales y ofrecen más plazas de aparcamiento. Sin embargo, las viviendas en El Bosque también ofrecen un precio competitivo gracias a sus precios proyectados más bajos. El análisis espacial presentado en el mapa le permite visualizar la ubicación de estas instalaciones en la zona norte de la ciudad, lo que facilita la evaluación geográfica de las opciones disponibles.
Se construye la segunda base, en donde se encuentran los apartementos ubicados en la zona sur.
# Visualización de información relevante de la base original.
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>
str(vivienda)
## spc_tbl_ [8,322 × 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ id : num [1:8322] 1147 1169 1350 5992 1212 ...
## $ zona : chr [1:8322] "Zona Oriente" "Zona Oriente" "Zona Oriente" "Zona Sur" ...
## $ piso : chr [1:8322] NA NA NA "02" ...
## $ estrato : num [1:8322] 3 3 3 4 5 5 4 5 5 5 ...
## $ preciom : num [1:8322] 250 320 350 400 260 240 220 310 320 780 ...
## $ areaconst : num [1:8322] 70 120 220 280 90 87 52 137 150 380 ...
## $ parqueaderos: num [1:8322] 1 1 2 3 1 1 2 2 2 2 ...
## $ banios : num [1:8322] 3 2 2 5 2 3 2 3 4 3 ...
## $ habitaciones: num [1:8322] 6 3 4 3 3 3 3 4 6 3 ...
## $ tipo : chr [1:8322] "Casa" "Casa" "Casa" "Casa" ...
## $ barrio : chr [1:8322] "20 de julio" "20 de julio" "20 de julio" "3 de julio" ...
## $ longitud : num [1:8322] -76.5 -76.5 -76.5 -76.5 -76.5 ...
## $ latitud : num [1:8322] 3.43 3.43 3.44 3.44 3.46 ...
## - 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_character" "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"
## .. ..$ parqueaderos: list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ banios : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ habitaciones: 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>
summary(vivienda)
## id zona piso estrato
## Min. : 1 Length:8322 Length:8322 Min. :3.000
## 1st Qu.:2080 Class :character Class :character 1st Qu.:4.000
## Median :4160 Mode :character Mode :character Median :5.000
## Mean :4160 Mean :4.634
## 3rd Qu.:6240 3rd Qu.:5.000
## Max. :8319 Max. :6.000
## NA's :3 NA's :3
## preciom areaconst parqueaderos banios
## Min. : 58.0 Min. : 30.0 Min. : 1.000 Min. : 0.000
## 1st Qu.: 220.0 1st Qu.: 80.0 1st Qu.: 1.000 1st Qu.: 2.000
## Median : 330.0 Median : 123.0 Median : 2.000 Median : 3.000
## Mean : 433.9 Mean : 174.9 Mean : 1.835 Mean : 3.111
## 3rd Qu.: 540.0 3rd Qu.: 229.0 3rd Qu.: 2.000 3rd Qu.: 4.000
## Max. :1999.0 Max. :1745.0 Max. :10.000 Max. :10.000
## NA's :2 NA's :3 NA's :1605 NA's :3
## habitaciones tipo barrio longitud
## Min. : 0.000 Length:8322 Length:8322 Min. :-76.59
## 1st Qu.: 3.000 Class :character Class :character 1st Qu.:-76.54
## Median : 3.000 Mode :character Mode :character Median :-76.53
## Mean : 3.605 Mean :-76.53
## 3rd Qu.: 4.000 3rd Qu.:-76.52
## Max. :10.000 Max. :-76.46
## NA's :3 NA's :3
## latitud
## Min. :3.333
## 1st Qu.:3.381
## Median :3.416
## Mean :3.418
## 3rd Qu.:3.452
## Max. :3.498
## NA's :3
dim(vivienda)
## [1] 8322 13
names(vivienda)
## [1] "id" "zona" "piso" "estrato" "preciom"
## [6] "areaconst" "parqueaderos" "banios" "habitaciones" "tipo"
## [11] "barrio" "longitud" "latitud"
#Información en el campo tipo
vivienda %>%
distinct(tipo)
## # A tibble: 3 × 1
## tipo
## <chr>
## 1 Casa
## 2 Apartamento
## 3 <NA>
#Información en el campo zona
vivienda %>%
distinct(zona)
## # A tibble: 6 × 1
## zona
## <chr>
## 1 Zona Oriente
## 2 Zona Sur
## 3 Zona Norte
## 4 Zona Oeste
## 5 Zona Centro
## 6 <NA>
#Construcción de la base2 con los filtros requeridos
base2 <- vivienda %>%
filter(tipo == "Apartamento",
zona == "Zona Sur")
Se presentan los primeros 3 registros de la base y algunas tablas para validar el resultado.
#Primeros registros
head(base2,3)
## # 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>
#Tamaño de la base
dim(base2)
## [1] 2787 13
#Validación de variables
table(base2$tipo)
##
## Apartamento
## 2787
table(base2$zona)
##
## Zona Sur
## 2787
#Tabla cruzada
table(base2$tipo, base2$zona)
##
## Zona Sur
## Apartamento 2787
#Resumen de la base
head(base2)
## # A tibble: 6 × 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 1241 Zona S… <NA> 3 135 117 NA 2 3
## 5 5370 Zona S… <NA> 3 135 78 NA 1 3
## 6 6975 Zona S… 06 4 220 75 1 2 3
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
str(base2)
## spc_tbl_ [2,787 × 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ id : num [1:2787] 5098 698 8199 1241 5370 ...
## $ zona : chr [1:2787] "Zona Sur" "Zona Sur" "Zona Sur" "Zona Sur" ...
## $ piso : chr [1:2787] "05" "02" NA NA ...
## $ estrato : num [1:2787] 4 3 6 3 3 4 3 3 3 4 ...
## $ preciom : num [1:2787] 290 78 875 135 135 220 210 105 115 220 ...
## $ areaconst : num [1:2787] 96 40 194 117 78 75 72 68 58 84 ...
## $ parqueaderos: num [1:2787] 1 1 2 NA NA 1 2 NA 1 NA ...
## $ banios : num [1:2787] 2 1 5 2 1 2 2 2 2 2 ...
## $ habitaciones: num [1:2787] 3 2 3 3 3 3 3 3 2 3 ...
## $ tipo : chr [1:2787] "Apartamento" "Apartamento" "Apartamento" "Apartamento" ...
## $ barrio : chr [1:2787] "acopi" "aguablanca" "aguacatal" "alameda" ...
## $ longitud : num [1:2787] -76.5 -76.5 -76.6 -76.5 -76.5 ...
## $ latitud : num [1:2787] 3.45 3.4 3.46 3.44 3.44 ...
## - 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_character" "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"
## .. ..$ parqueaderos: list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ banios : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ habitaciones: 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>
summary(base2)
## id zona piso estrato
## Min. : 3 Length:2787 Length:2787 Min. :3.00
## 1st Qu.:2292 Class :character Class :character 1st Qu.:4.00
## Median :4004 Mode :character Mode :character Median :5.00
## Mean :4131 Mean :4.63
## 3rd Qu.:5876 3rd Qu.:5.00
## Max. :8302 Max. :6.00
##
## preciom areaconst parqueaderos banios
## Min. : 75.0 Min. : 40.00 Min. : 1.000 Min. :0.000
## 1st Qu.: 175.0 1st Qu.: 65.00 1st Qu.: 1.000 1st Qu.:2.000
## Median : 245.0 Median : 85.00 Median : 1.000 Median :2.000
## Mean : 297.3 Mean : 97.47 Mean : 1.415 Mean :2.488
## 3rd Qu.: 335.0 3rd Qu.:110.00 3rd Qu.: 2.000 3rd Qu.:3.000
## Max. :1750.0 Max. :932.00 Max. :10.000 Max. :8.000
## NA's :406
## habitaciones tipo barrio longitud
## Min. :0.000 Length:2787 Length:2787 Min. :-76.57
## 1st Qu.:3.000 Class :character Class :character 1st Qu.:-76.54
## Median :3.000 Mode :character Mode :character Median :-76.53
## Mean :2.966 Mean :-76.53
## 3rd Qu.:3.000 3rd Qu.:-76.52
## Max. :6.000 Max. :-76.46
##
## latitud
## Min. :3.334
## 1st Qu.:3.370
## Median :3.383
## Mean :3.390
## 3rd Qu.:3.406
## Max. :3.497
##
Mapa de ubicación de los apartamentos de la zona sur.
library(ggplot2)
ggplot(base2, aes(x = longitud, y = latitud)) +
geom_point(color = "darkgreen", alpha = 0.6) +
labs(title = "Ubicación de apartamentos en la zona sur",
x = "Longitud",
y = "Latitud") +
theme_minimal()
Al igual que en el caso anterior, algunos puntos pueden aparecer fuera de la zona esperada debido a errores de clasificación en la variable zona o inconsistencias en las coordenadas geográficas.
Se realiza un análisis enfocado en identificar la relación que tienen los precios de las casas frente a el área construida, el estrato, el numero de baños, el numero de habitaciones y la zona donde se ubica la vivienda.
# Análisis exploratorio
#install.packages("plotly")
library(plotly)
#Relación entre área construida y precio
plot_ly(base2,
x = ~areaconst,
y = ~preciom,
type = "scatter",
mode = "markers",
marker = list(color = "darkgreen")) %>%
layout(title = "Relación entre área construida y precio (Apartamentos)",
xaxis = list(title = "Área construida"),
yaxis = list(title = "Precio (millones)"))
Este gráfico permite ver que no hay una gran concentración de viviendas en el punto y alrededor de donde se encuentra visualmente los apartamentos que cuestan 850 millones y miden 300 metros.
#Precio de la vivienda según estrato
plot_ly(base2,
x = ~factor(estrato),
y = ~preciom,
type = "box") %>%
layout(title = "Precio de apartamentos según estrato",
xaxis = list(title = "Estrato"),
yaxis = list(title = "Precio"))
Vemos que hay mayor concentración de viviendas en el estrato 6 con el precio de 850 millones, que en el estrato 5.
#Relación entre número de baños y precio
plot_ly(base2,
x = ~banios,
y = ~preciom,
type = "scatter",
mode = "markers") %>%
layout(title = "Relación entre baños y precio",
xaxis = list(title = "Número de baños"),
yaxis = list(title = "Precio"))
Observamos que hay casas que cumplen la condición de tener los baños requeridos.
# Relación entre número de habitaciones y precio
plot_ly(base2,
x = ~habitaciones,
y = ~preciom,
type = "scatter",
mode = "markers") %>%
layout(title = "Relación entre habitaciones y precio",
xaxis = list(title = "Habitaciones"),
yaxis = list(title = "Precio"))
Las habitaciones también satisfacen la condición.
#Precio de viviendas según zona
plot_ly(vivienda,
x = ~zona,
y = ~preciom,
type = "box") %>%
layout(title = "Precio de viviendas según zona",
xaxis = list(title = "Zona"),
yaxis = list(title = "Precio"))
## Warning: Ignoring 3 observations
Utilizando toda la base, se puede evidenciar que la zona cuenta con apartamentos del precio.
Construcción del modelo de regresión lineal múltiple.
set.seed(123)
train_id <- sample(1:nrow(base2), 0.7*nrow(base2))
train <- base2[train_id, ]
test <- base2[-train_id, ]
modelo2 <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios,
data = train)
summary(modelo2)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = train)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1124.33 -42.59 -1.62 39.89 922.71
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -262.35633 18.79752 -13.957 < 2e-16 ***
## areaconst 1.32328 0.06913 19.142 < 2e-16 ***
## estrato 61.72529 3.72892 16.553 < 2e-16 ***
## habitaciones -25.01772 4.67804 -5.348 1.01e-07 ***
## parqueaderos 71.30553 4.65773 15.309 < 2e-16 ***
## banios 49.17107 4.14149 11.873 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 99.73 on 1655 degrees of freedom
## (289 observations deleted due to missingness)
## Multiple R-squared: 0.7466, Adjusted R-squared: 0.7458
## F-statistic: 975.1 on 5 and 1655 DF, p-value: < 2.2e-16
Interpretación de los coeficientes del modelo
El modelo de regresión lineal se construyó con el objetivo de explicar el precio de las viviendas (preciom) a partir de algunas características del inmueble: área construida, estrato socioeconómico, número de habitaciones, número de parqueaderos y número de baños. A continuación se presenta la interpretación de cada uno de los coeficientes estimados.
Área construida
El coeficiente asociado al área construida es 1.323 y resulta estadísticamente significativo (p < 0.001).
Esto significa que, manteniendo constantes las demás variables del modelo, un aumento de un metro cuadrado en el área construida se asocia, en promedio, con un incremento de aproximadamente 1.32 millones de pesos en el precio de la vivienda.
Este resultado es coherente con el comportamiento del mercado inmobiliario, ya que las viviendas con mayor espacio construido suelen tener un mayor valor comercial.
Estrato socioeconómico
El coeficiente estimado para el estrato socioeconómico es 61.73, y también es estadísticamente significativo (p < 0.001).
Esto indica que, manteniendo constantes las demás características del inmueble, un aumento de una unidad en el estrato se asocia con un incremento promedio de aproximadamente 61.7 millones de pesos en el precio de la vivienda.
Este resultado es consistente con la realidad del mercado inmobiliario, ya que las viviendas ubicadas en estratos más altos generalmente se encuentran en zonas con mejores condiciones urbanas, mayor infraestructura y mejores servicios, lo cual incrementa su valor.
Número de habitaciones
El coeficiente asociado al número de habitaciones es -25.02, y es estadísticamente significativo (p < 0.001).
Esto indica que, manteniendo constantes las demás variables, un aumento de una habitación adicional se asocia con una disminución promedio de aproximadamente 25 millones de pesos en el precio por metro cuadrado.
Aunque este resultado puede parecer contraintuitivo, una posible explicación es que, manteniendo constante el área construida, más habitaciones implican espacios más pequeños, lo que podría reducir el valor por metro cuadrado del inmueble.
Número de parqueaderos
El coeficiente asociado al número de parqueaderos es 71.31, y resulta estadísticamente significativo (p < 0.001).
Esto significa que, manteniendo constantes las demás variables, cada parqueadero adicional se asocia con un incremento promedio de aproximadamente 71.3 millones de pesos en el precio de la vivienda.
Este resultado es coherente con la lógica del mercado inmobiliario urbano, donde la disponibilidad de parqueaderos es una característica muy valorada por los compradores.
Número de baños
El coeficiente estimado para el número de baños es 49.17, y también es estadísticamente significativo (p < 0.001).
Esto indica que, manteniendo constantes las demás variables, cada baño adicional se asocia con un incremento promedio de aproximadamente 49.2 millones de pesos en el precio de la vivienda.
Este resultado también es consistente con el mercado inmobiliario, ya que un mayor número de baños suele representar mayor comodidad y funcionalidad para los habitantes.
Coeficiente de determinación (R²) Interpretación
El modelo presenta un R² de 0.7466, lo que indica que aproximadamente el 74.66% de la variabilidad en el precio de las viviendas es explicada por las variables incluidas en el modelo: área construida, estrato, número de habitaciones, número de parqueaderos y número de baños.
El R² ajustado es 0.7458, lo cual muestra que la capacidad explicativa del modelo se mantiene prácticamente igual incluso después de considerar el número de variables incluidas.
Ajuste del modelo
El valor del R² indica un buen nivel de ajuste, ya que el modelo logra explicar cerca del 75% de la variación en los precios de las viviendas.
Sin embargo, alrededor del 25% de la variación en el precio permanece sin explicar, lo que sugiere que existen otros factores que también influyen en el valor de los inmuebles y que no están incluidos en el modelo actual.
En general, los resultados obtenidos son coherentes con la lógica del mercado inmobiliario, donde variables como el tamaño de la vivienda, el estrato socioeconómico, el número de baños y la disponibilidad de parqueaderos tienen una influencia importante en la determinación del precio.
Implicaciones
Los resultados del modelo sugieren que el área construida y el estrato socioeconómico son dos de los factores más relevantes en la determinación del precio de las viviendas en la muestra analizada.
Además, características como el número de baños y la disponibilidad de parqueaderos también tienen un efecto positivo y significativo sobre el valor del inmueble.
Estos resultados permiten identificar cuáles son las características que más influyen en el precio de las viviendas y pueden servir como referencia para la valoración de inmuebles dentro del mercado analizado.
Posibles mejoras del modelo
El modelo podría mejorarse mediante la incorporación de otras variables que también influyen en el precio de las viviendas, por ejemplo:
el barrio específico donde se ubica la vivienda
la antigüedad del inmueble
características del entorno o ubicación
cercanía a centros comerciales, transporte o zonas verdes
Asimismo, podrían explorarse modelos no lineales o interacciones entre variables, con el fin de capturar de forma más precisa la relación entre las características del inmueble y su precio en el mercado.
Validación de supuestos.
# Gráficos de diagnóstico del modelo
par(mfrow=c(2,2))
plot(modelo2)
Gráfico: Residuals vs Fitted
Interpretación: El gráfico de residuos frente a valores ajustados permite evaluar si la relación entre las variables explicativas y la variable de respuesta es aproximadamente lineal. En un modelo correctamente especificado, los residuos deberían distribuirse de forma aleatoria alrededor de cero sin mostrar patrones claros.
En este gráfico se observa que la mayoría de los residuos se concentran alrededor de cero para valores ajustados bajos y medios. Sin embargo, a medida que aumentan los valores ajustados, la dispersión de los residuos también aumenta y aparecen algunos valores atípicos. Además, la línea roja presenta una ligera tendencia ascendente, lo que podría indicar que la relación no es completamente lineal o que el modelo no captura toda la estructura de los datos.
En general, no se observa una curvatura fuerte, pero sí indicios de que el modelo podría mejorarse.
Sugerencias
Para mejorar el ajuste del modelo se puede considerar:
Transformaciones de variables.
Inclusión de términos no lineales o interacciones.
Evaluar modelos más flexibles.
Gráfico: Normal Q-Q
Interpretación: El gráfico Q-Q compara la distribución de los residuos con una distribución normal teórica. Si los residuos siguen una distribución aproximadamente normal, los puntos deberían alinearse sobre la línea diagonal.
En este caso, los puntos siguen la diagonal en la parte central de la distribución, lo que indica que la normalidad se cumple aproximadamente en esa zona. Sin embargo, se observan desviaciones claras en las colas, especialmente en los valores extremos del lado derecho, lo que sugiere la presencia de residuos extremos o colas más pesadas que las de una distribución normal.
Esto indica que el supuesto de normalidad no se cumple completamente.
Sugerencias
Para mejorar esta suposición se podría considerar:
Aplicar una transformación a la variable de respuesta (por ejemplo, logaritmo del precio).
Identificar y analizar posibles valores atípicos.
Utilizar modelos robustos que sean menos sensibles a la no normalidad.
Gráfico: Scale-Location
Interpretación: Este gráfico permite evaluar si la varianza de los residuos es constante a lo largo de los valores ajustados.
En la figura se observa una tendencia creciente en la dispersión de los residuos estandarizados a medida que aumentan los valores ajustados. La línea roja también muestra una ligera pendiente ascendente. Este patrón sugiere la presencia de heterocedasticidad, es decir, que la varianza de los errores no es constante.
Este comportamiento indica que el modelo puede estar subestimando la variabilidad en valores altos de la variable dependiente.
Sugerencias
Si existe heterocedasticidad se puede considerar:
Transformación de la variable de respuesta (por ejemplo logaritmo).
Regresión ponderada (Weighted Least Squares).
Uso de errores estándar robustos.
Gráfico: Residuals vs Leverage
Interpretación: Este gráfico permite identificar observaciones con alto apalancamiento y posible influencia en el ajuste del modelo. Las líneas punteadas representan la distancia de Cook, que ayuda a detectar puntos potencialmente influyentes.
La mayoría de las observaciones se concentran cerca del origen, lo que indica bajo apalancamiento. No obstante, se observan algunos puntos hacia la parte derecha del gráfico con valores de leverage relativamente altos y residuos grandes. Estos puntos podrían tener una mayor influencia sobre los coeficientes del modelo.
Aunque la mayoría de los puntos se encuentran dentro de los límites de la distancia de Cook, algunas observaciones específicas podrían requerir revisión adicional.
Sugerencias
Una vez identificadas las observaciones potencialmente influyentes se recomienda:
Revisar los datos para descartar errores de registro.
Analizar el impacto de estas observaciones sobre el modelo.
Considerar el uso de métodos de regresión robusta si los puntos influyentes afectan significativamente el ajuste.
Precio de la vivienda con las características.
# Datos de la vivienda a evaluar
nuevo_apartamento <- data.frame(
areaconst = c(300,300),
estrato = c(5,6),
habitaciones = c(5,5),
parqueaderos = c(3,3),
banios = c(3,3)
)
nuevo_apartamento
## areaconst estrato habitaciones parqueaderos banios
## 1 300 5 5 3 3
## 2 300 6 5 3 3
# Prediccion del precio con el modelo
prediccion2 <- predict(modelo2, newdata = nuevo_apartamento)
prediccion2
## 1 2
## 679.5954 741.3207
resultado_pred2 <- cbind(nuevo_apartamento, precio_estimado = prediccion2)
resultado_pred2
## areaconst estrato habitaciones parqueaderos banios precio_estimado
## 1 300 5 5 3 3 679.5954
## 2 300 6 5 3 3 741.3207
# apartamentos con características similares
ofertas2 <- base2 %>%
filter(
estrato %in% c(5,6),
parqueaderos >= 2,
banios >= 2,
habitaciones >= 4,
between(areaconst,250,350)
)
# Predecir precios con el modelo
ofertas2$precio_estimado <- predict(modelo2, newdata = ofertas2)
# Viviendas que cumplen el presupuesto
ofertas_potenciales2 <- ofertas2 %>%
filter(precio_estimado <= 850)
# Top 5
ofertas_final2 <- ofertas_potenciales2 %>%
head(5)
ofertas_final2
## # A tibble: 5 × 14
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 6175 Zona S… 05 5 350 270 3 3 4
## 2 4962 Zona S… <NA> 6 980 274 3 4 4
## 3 5306 Zona S… 12 5 650 275 2 5 5
## 4 8113 Zona S… 02 5 410 296. 2 4 4
## 5 7658 Zona S… 06 5 520 320 2 4 4
## # ℹ 5 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>,
## # precio_estimado <dbl>
View(ofertas_final2)
# Mapa
library(plotly)
plot_ly(ofertas_final2,
x = ~longitud,
y = ~latitud,
type = "scatter",
mode = "markers",
marker = list(size = 12,
color = "blue"),
text = ~paste(
"Precio estimado:", round(precio_estimado,1), "millones",
"<br>Área:", areaconst,
"<br>Estrato:", estrato,
"<br>Baños:", banios,
"<br>Habitaciones:", habitaciones
),
hoverinfo = "text") %>%
layout(title = "Ofertas potenciales de apartamentos (Zona Sur)",
xaxis = list(title = "Longitud"),
yaxis = list(title = "Latitud"))
Selección de Propiedades Potenciales
Con base en el modelo de regresión estimado previamente, seleccionamos propiedades que cumplían los criterios para una segunda residencia. En concreto, nos centramos en apartamentos ubicados en la zona sur de la ciudad, de clase socioeconómica 5 o superior, con al menos cuatro dormitorios, varios baños y estacionamiento seguro. Se espera que estas características proporcionen un espacio habitable amplio y confortable.
Posteriormente, utilizamos el modelo para estimar el precio esperado de cada propiedad y comparamos el precio previsto por el modelo con las características estructurales reales de la propiedad.
Mediante este proceso, seleccionamos cinco apartamentos ubicados en la zona sur de la ciudad (Capri, Ciudad Jardín, Ciudad de la Pasoancho y Cuarto de Régua).
Estas propiedades varían en tamaño, aproximadamente entre 270 y 320 metros cuadrados, ofreciendo amplios espacios. Asimismo, todas las propiedades cuentan con una generosa superficie habitable, con dos o tres plazas de aparcamiento, de tres a cinco baños y de cuatro a cinco dormitorios.
El precio estimado de las unidades modelo oscila entre aproximadamente 664 millones de pesos y 781 millones de pesos, con variaciones significativas según las características específicas de cada unidad.
Análisis de la propiedad
Las unidades en Cuarto de Legua ofrecen superficies relativamente amplias (más de 295 metros cuadrados) y múltiples baños y recámaras, lo que las convierte en opciones atractivas para familias que buscan más espacio.
Por el contrario, los departamentos en Ciudad Jardín tienen los precios estimados más altos, probablemente debido a su ubicación y otras características como la cantidad de baños y la amplitud de la superficie.
Los departamentos en Capri tienen precios estimados relativamente más bajos dentro del grupo analizado, pero aun así ofrecen características atractivas como múltiples estacionamientos, baños y recámaras.
De igual manera, las unidades en Ciudad de la Pasoancho ofrecen cinco recámaras y cinco baños, lo que las convierte en opciones particularmente atractivas para familias numerosas o quienes buscan más espacio.
Recomendaciones
Considerando las características analizadas, las propiedades ubicadas en Cuarto de Regua y Ciudad de la Pasoancho ofrecen amplios espacios habitables, múltiples recámaras e incluso estacionamiento, lo que las convierte en opciones particularmente atractivas.
Por otro lado, si busca una opción más asequible entre las propiedades analizadas, también vale la pena considerar las ubicadas en Capri.
Finalmente, la ubicación geográfica (longitud y latitud) de estas propiedades, junto con el análisis espacial, le permite visualizar su distribución en la zona sur de la ciudad, lo que le ayudará a comparar diversas opciones y a tomar decisiones de compra informadas.