Introducción

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")

Vivienda 1: Casa.

1

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.

2

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.

3

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:

  • El barrio específico donde se ubica la vivienda
  • La antigüedad del inmueble
  • Características del entorno.

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.

4

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:

  • Transformaciones de variables
  • Inclusión de términos no lineales
  • Modelos más flexibles
  1. Normalidad de los residuos (Q-Q Plot)

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.

  1. Homocedasticidad (Scale-Location).

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:

  • Transformación de la variable de respuesta (p. ej., transformación logarítmica del precio)
  • Análisis de regresión ponderada
  • Utilice errores estándar robustos
  1. Observaciones influyentes (Residuals vs Leverage)

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.

5

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

6. Ofertas potenciales.

# 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.

Vivienda 2: Apartamento.

1

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.

2

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.

3

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.

4

Validación de supuestos.

# Gráficos de diagnóstico del modelo

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

  1. Linealidad (Residuals vs Fitted)

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.

  1. Normalidad de los residuos (Q-Q Plot)

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.

  1. Homocedasticidad (Scale-Location)

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.

  1. Observaciones influyentes (Residuals vs Leverage)

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.

5

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

6. Ofertas potenciales.

# 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.