Primero debemos cargar la base de datos de los inmuebles y abrirlo

library(readr)
Inmuebles_Disponibles_Para_La_Venta_20250513 <- read_csv("C:/Users/fidel/Downloads/Inmuebles_Disponibles_Para_La_Venta_20250513.csv")
## Rows: 448 Columns: 12
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (8): Ciudad, Departamento, Barrio, Direccion, Detalle Disponibilidad, Es...
## dbl (4): Codigo, Area Terreno, Area Construida, Precio
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
View(Inmuebles_Disponibles_Para_La_Venta_20250513)

Para más comodidad cambiamos el nombre de la base de datos a un nombre más corto como “inmuebles”

inmuebles <- Inmuebles_Disponibles_Para_La_Venta_20250513

rm(Inmuebles_Disponibles_Para_La_Venta_20250513)

A. Preguntas de Analisis 1. Analisis inicial y limpieza Para averiguar el numero de columnas, registros y el tipo de datos utilizamos los siguientes codigos

nrow(inmuebles)
## [1] 448
ncol(inmuebles)
## [1] 12
sapply(inmuebles, class)
##                 Codigo                 Ciudad           Departamento 
##              "numeric"            "character"            "character" 
##                 Barrio              Direccion           Area Terreno 
##            "character"            "character"              "numeric" 
##        Area Construida Detalle Disponibilidad                Estrato 
##              "numeric"            "character"            "character" 
##                 Precio       Tipo de Inmueble      Datos Adicionales 
##              "numeric"            "character"            "character"

2. Valores nulos y duplicados: averiguamos cuantas columnas tienen valores nulos (NA) y que porcentaje representan

colSums(is.na(inmuebles)) 
##                 Codigo                 Ciudad           Departamento 
##                      0                      0                      0 
##                 Barrio              Direccion           Area Terreno 
##                    389                      0                      0 
##        Area Construida Detalle Disponibilidad                Estrato 
##                      0                      0                      0 
##                 Precio       Tipo de Inmueble      Datos Adicionales 
##                      0                      0                    371
colMeans(is.na(inmuebles)) * 100 #para saber el porcentaje#
##                 Codigo                 Ciudad           Departamento 
##                0.00000                0.00000                0.00000 
##                 Barrio              Direccion           Area Terreno 
##               86.83036                0.00000                0.00000 
##        Area Construida Detalle Disponibilidad                Estrato 
##                0.00000                0.00000                0.00000 
##                 Precio       Tipo de Inmueble      Datos Adicionales 
##                0.00000                0.00000               82.81250

Luego averiguamos si existen registros duplicados con el siguiente comando

sum(duplicated(inmuebles))
## [1] 0

3. Depuración de datos: usando boxplot veremos si hay valores atípicos en las columnas de precio, area construida y area de terreno, y agregamos un codigo para desactivar la notación científica que usa R con los números extremadamente grandes

options(scipen = 999) 
boxplot(inmuebles$Precio, 
        main = "distribucion del Precio", 
        ylab = "Precio en pesos", 
        col = "red", 
        outline = TRUE)

boxplot(inmuebles$`Area Construida`, 
        main = "distribucion del area construida", 
        ylab = "area en metros", 
        col = "red", 
        outline = TRUE)

boxplot(inmuebles$`Area Terreno`, 
        main = "distribucion del area de terreno", 
        ylab = "area en metros", 
        col = "red", 
        outline = TRUE)

Como resultado vemos que en ambas categorias, precio y areas, existen valores atipicos los cuales se alejan mucho del promedio del resto de los datos

B. Análisis Descriptivo 4. Distribuciones: hallamos la distribucion de los precios para saber si es normal o sesgada

library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.4.3
ggplot(inmuebles, aes(x = Precio)) +
  geom_histogram(bins = 30, fill = "skyblue", color = "black") +
  labs(title = "Distribución del Precio de los Inmuebles",
       x = "Precio (en pesos)", y = "Frecuencia") +
  theme_minimal()

Con el siguiente cogigo averiguaremos si la distribucion de precios es

#install.packages("e1071")#
library(e1071)
## Warning: package 'e1071' was built under R version 4.4.3
skewness(inmuebles$Precio, na.rm = TRUE)
## [1] 7.256093

Este resultado del skewness de 7.25 es un valor considerado muy alto y positivo, lo que implica que la distribución del precio está fuertemente sesgada a la derecha, lo que significa que los precios de la mayoría de los inmuebles tienen precios relativamente bajos

Luego averiguamos cual es el inmueble mas comun por medio de un grafico de barras

library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.4.3
## Warning: package 'dplyr' was built under R version 4.4.3
## Warning: package 'lubridate' was built under R version 4.4.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ stringr   1.5.1
## ✔ forcats   1.0.0     ✔ tibble    3.2.1
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.0.4     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(ggplot2)

ggplot(inmuebles, aes(x = `Tipo de Inmueble`)) + 
  geom_bar(fill = "steelblue") + 
  labs(title = "Tipo de Inmueble", y = "Frecuencia") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1))

B. Estadísticas clave: usando las columnas con tipo de dato numerico, Calcular media, mediana, desviación estándar, cuartiles y tablas de frecuencias

Media

library(dplyr)

inmuebles %>% 
  summarise(
    across(
      c(Precio, Codigo, `Area Construida`, `Area Terreno`),
      list(media = mean),
      na.rm = TRUE
    )
  )
## Warning: There was 1 warning in `summarise()`.
## ℹ In argument: `across(...)`.
## Caused by warning:
## ! The `...` argument of `across()` is deprecated as of dplyr 1.1.0.
## Supply arguments directly to `.fns` through an anonymous function instead.
## 
##   # Previously
##   across(a:b, mean, na.rm = TRUE)
## 
##   # Now
##   across(a:b, \(x) mean(x, na.rm = TRUE))
## # A tibble: 1 × 4
##   Precio_media Codigo_media `Area Construida_media` `Area Terreno_media`
##          <dbl>        <dbl>                   <dbl>                <dbl>
## 1      9.37e12       17680.                  11552.             1619546.

Mediana

inmuebles %>% 
  summarise(
    across(
      c(Precio, Codigo, `Area Construida`, `Area Terreno`),
      list(mediana = median),
      na.rm = TRUE
    )
  )
## # A tibble: 1 × 4
##   Precio_mediana Codigo_mediana `Area Construida_mediana` `Area Terreno_mediana`
##            <dbl>          <dbl>                     <dbl>                  <dbl>
## 1   165205000000         18292.                         0                      0

desviación estándar

inmuebles %>%
  summarise(
    across(
      c(Precio, Codigo, `Area Construida`, `Area Terreno`),
      sd,
      na.rm = TRUE
    )
  )
## # A tibble: 1 × 4
##    Precio Codigo `Area Construida` `Area Terreno`
##     <dbl>  <dbl>             <dbl>          <dbl>
## 1 3.82e13  2543.           128518.      18588576.

cuartiles

summary(inmuebles[, c("Precio", "Codigo", "Area Construida", "Area Terreno")])
##      Precio                    Codigo      Area Construida  
##  Min.   :              0   Min.   : 2330   Min.   :      0  
##  1st Qu.:   125725000000   1st Qu.:18129   1st Qu.:      0  
##  Median :   165205000000   Median :18292   Median :      0  
##  Mean   :  9372905838390   Mean   :17680   Mean   :  11552  
##  3rd Qu.:  1861440000000   3rd Qu.:18472   3rd Qu.:      0  
##  Max.   :452337898200000   Max.   :19353   Max.   :2272400  
##   Area Terreno      
##  Min.   :        0  
##  1st Qu.:        0  
##  Median :        0  
##  Mean   :  1619546  
##  3rd Qu.:        0  
##  Max.   :321719700

tablas de frecuencias

lapply(inmuebles[c("Ciudad", "Departamento", "Barrio", "Detalle Disponibilidad", "Estrato", "Tipo de Inmueble")], table)
## $Ciudad
## 
##                    AGUAZUL                  ANGOSTURA 
##                          3                          1 
##                     ARMERO               BARRANQUILLA 
##                          2                         14 
##                    BITUIMA                     BOGOTA 
##                          1                         34 
##            BOLIVAR - CAUCA                       BUGA 
##                          1                          5 
##                       CALI           CALIMA EL DARIEN 
##                          7                         10 
##          CARMEN DE BOLIVAR                  CARTAGENA 
##                          1                          3 
##                   CAUCASIA                       CHIA 
##                          1                          2 
##                     CUCUTA                     CURITI 
##                          9                          1 
##                      DAGUA                  EL AGUILA 
##                          1                          1 
##                  EL PLAYON                   EL ROSAL 
##                          1                          1 
##                   ENVIGADO                      FUNZA 
##                          1                          1 
##                   GIRARDOT                     IBAGUE 
##                          4                          1 
##                  LA CALERA                  LA DORADA 
##                          1                          1 
##                LA VIRGINIA                 LOS PATIOS 
##                          1                          1 
##                     MADRID                  MANIZALES 
##                          1                         13 
##                   MARSELLA                   MEDELLIN 
##                          1                          5 
##                   MONTERIA                    PEREIRA 
##                          6                         12 
##                    PIEDRAS               PUERTO LOPEZ 
##                          1                          1 
##                   RICAURTE SAN ANTONIO DEL TEQUENDAMA 
##                          1                          2 
##     SANTANDER DE QUILICHAO                      SOATA 
##                          2                          1 
##                   SOGAMOSO                     TARAZA 
##                          1                          1 
##                      TENJO                       TIBU 
##                          1                          1 
##                      TURBO                 VILLA RICA 
##                          1                          1 
##              VILLAVICENCIO                      YUMBO 
##                        285                          1 
## 
## $Departamento
## 
##          ANTIOQUIA          ATLÁNTICO            BOLÍVAR             BOYACÁ 
##                 10                 14                  4                  2 
##             CALDAS           CASANARE              CAUCA            CÓRDOBA 
##                 14                  3                  4                  6 
##       CUNDINAMARCA               META NORTE DE SANTANDER          RISARALDA 
##                 49                286                 11                 14 
##          SANTANDER             TOLIMA    VALLE DEL CAUCA 
##                  2                  4                 25 
## 
## $Barrio
## 
##             AV 30 DE AGOSTO                  BELLAVISTA 
##                          10                           1 
##                      CENTRO        CIUDADELA CHIPICHAPE 
##                           3                           1 
## CONDOMINIO CAMPESTRE MONACO     CORREGIMIENTO EL CARMEN 
##                           1                           1 
##                   EL CENTRO                     EL HOYO 
##                           1                           1 
##                    EL PRADO                    GUACANDÁ 
##                           1                           1 
##            JOSE MARIA CABAL                   LA CALERA 
##                           4                           1 
##        PARQUE IND CAUCADESA PARQUE INDUSTRIAL CAUCADESA 
##                           1                           1 
##            PRADOS DEL NORTE               SANTA MATILDE 
##                           4                           1 
##                       SINAI                        SUBA 
##                          10                           1 
##                     TINTALA           VEREDA CHAMBIMBAL 
##                           1                           1 
##          VEREDA DE CAMBULAR             VEREDA FONQUETA 
##                           1                           1 
##              VEREDA PALERMO               VILLA DEL SUR 
##                          10                           1 
## 
## $`Detalle Disponibilidad`
## 
##                         COMERCIALIZABLE         COMERCIALIZABLE CON RESTRICCION 
##                                     319                                      91 
## COMERCIALIZABLE CON RESTRICCION FIDUCIA                 COMERCIALIZABLE FIDUCIA 
##                                       1                                      12 
##                COMERCIALIZABLE TERCEROS        COMERCIALIZABLE VENTA ANTICIPADA 
##                                      11                                      13 
##                                 EN PUJA 
##                                       1 
## 
## $Estrato
## 
##      CINCO  COMERCIAL     CUATRO        DOS INDUSTRIAL      RURAL       SEIS 
##          8        321         13         32          3         36         18 
##       TRES        UNO 
##         16          1 
## 
## $`Tipo de Inmueble`
## 
##           APARTAMENTO                BODEGA                  CASA 
##                     5                     8                    14 
##               CLINICA              EDIFICIO     EDIFICIO VIVIENDA 
##                     3                     4                     2 
##                 FINCA                GARAJE                 HOTEL 
##                     8                     2                     1 
##                 LOCAL                  LOTE         LOTE AGRICOLA 
##                   304                     4                     5 
##        LOTE COMERCIAL LOTE CON CONSTRUCCION       LOTE INDUSTRIAL 
##                     3                     8                     4 
##            LOTE MIXTO   LOTE NO URBANIZABLE         LOTE VIVIENDA 
##                     6                     1                    38 
##               OFICINA 
##                    28

6. AGRUPACIONES: calcularemos el promedio del precio por estrato

library(dplyr)
options(scipen = 999)
inmuebles%>%
  group_by(Estrato)%>%summarise(Promedio_Precio = mean(Precio, na.rm = TRUE))
## # A tibble: 9 × 2
##   Estrato    Promedio_Precio
##   <chr>                <dbl>
## 1 CINCO              1.60e13
## 2 COMERCIAL          4.15e12
## 3 CUATRO             7.84e12
## 4 DOS                1.30e13
## 5 INDUSTRIAL         1.22e14
## 6 RURAL              3.08e13
## 7 SEIS               7.06e12
## 8 TRES               3.87e13
## 9 UNO                9.82e11

Ahora hallamos el promedio de precios por ciudad

inmuebles%>%
  group_by(Ciudad)%>%summarise(Promedio_Precio = mean(Precio, na.rm = TRUE))
## # A tibble: 48 × 2
##    Ciudad           Promedio_Precio
##    <chr>                      <dbl>
##  1 AGUAZUL                  1.39e13
##  2 ANGOSTURA                2.46e13
##  3 ARMERO                   4.73e12
##  4 BARRANQUILLA             4.88e12
##  5 BITUIMA                  4.81e12
##  6 BOGOTA                   5.27e13
##  7 BOLIVAR - CAUCA          7.38e12
##  8 BUGA                     9.65e13
##  9 CALI                     3.51e12
## 10 CALIMA EL DARIEN         2.19e13
## # ℹ 38 more rows

C. Análisis Espacial (Geográfico): (Si no hay coordenadas): Analizaremos los precios por departamento, y los representamos en un mapa coropléticos)

library(dplyr)
library(ggplot2)
library(sf)
## Warning: package 'sf' was built under R version 4.4.3
## Linking to GEOS 3.13.0, GDAL 3.10.1, PROJ 9.5.1; sf_use_s2() is TRUE
library(tmap)

Colombia <- st_read("C:/Users/fidel/Downloads/Nueva carpeta/MGN_2021_COLOMBIA/COLOMBIA")
## Reading layer `COLOMBIA' from data source 
##   `C:\Users\fidel\Downloads\Nueva carpeta\MGN_2021_COLOMBIA\COLOMBIA' 
##   using driver `ESRI Shapefile'
## Simple feature collection with 33 features and 9 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: -81.73562 ymin: -4.229406 xmax: -66.84722 ymax: 13.39473
## Geodetic CRS:  MAGNA-SIRGAS

Mapas y geolocalización: identificar como se reparten los niveles de precio por departamentos

En el siguiente codigo creamos una agrupacion donde solo esten los departamentos junto al promedio de precios de cada uno, luego juntamos esta base de datos con el shapefile de Colombia donde tenemos los datos geográficos, para finalmente con la informacion necesaria junta, crear el mapa por departamento distinguido por promedio de precio

precio_por_dpto <- inmuebles %>%
  group_by(Departamento) %>%
  summarise(PrecioPromedio = mean(Precio, na.rm = TRUE))


mapa <- left_join(Colombia, precio_por_dpto, by = c("DPTO_CNMBR" = "Departamento"))

tm_shape(mapa) +
  tm_polygons("PrecioPromedio",
              title = "Precio promedio",
              palette = "YlOrRd",
              style = "quantile") +
  tm_layout(main.title = "Mapa de precios por departamento en Colombia")
## 
## ── tmap v3 code detected ───────────────────────────────────────────────────────
## [v3->v4] `tm_polygons()`: instead of `style = "quantile"`, use fill.scale =
## `tm_scale_intervals()`.
## ℹ Migrate the argument(s) 'style', 'palette' (rename to 'values') to
##   'tm_scale_intervals(<HERE>)'
## [v3->v4] `tm_polygons()`: migrate the argument(s) related to the legend of the
## visual variable `fill` namely 'title' to 'fill.legend = tm_legend(<HERE>)'
## [v3->v4] `tm_layout()`: use `tm_title()` instead of `tm_layout(main.title = )`
## [cols4all] color palettes: use palettes from the R package cols4all. Run
## `cols4all::c4a_gui()` to explore them. The old palette name "YlOrRd" is named
## "brewer.yl_or_rd"
## Multiple palettes called "yl_or_rd" found: "brewer.yl_or_rd", "matplotlib.yl_or_rd". The first one, "brewer.yl_or_rd", is returned.
## 
## [plot mode] fit legend/component: Some legend items or map compoments do not
## fit well, and are therefore rescaled.
## ℹ Set the tmap option `component.autoscale = FALSE` to disable rescaling.

8. Patrones geográficos: Hallar si hay diferencia de precios entre las ciudades

vemos que hay ciudades como Buga, donde hay precios que superan por mucho el precio promedio de su propio territorio y el de ciudades vecinas, un escenario parecido esta presente en los precios de los inmuebles en Bogota

ggplot(inmuebles, aes(x = Ciudad, y = Precio)) +
  geom_boxplot(fill = "skyblue", outlier.color = "red") +
  theme_minimal() +
  labs(title = "Distribucion de precios por ciudad",
       x = "Ciudad",
       y = "Precio del inmueble") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

Ahora hallaremos la variacion del precio por metro cuadrado en barrios de estrato alto

nos encontramos con la situación de que en la columna de área construida hay muchos valores con cero (0), lo cual nos puede perjudicar los resultados, para ello, eliminamos los registros que en esa columna tengan cero

sin_areaconstruida_en_cero <- inmuebles %>%
  filter(`Area Construida` > 0)

la situacion actual deja solo 10 registros los cuales tienen valores mayores a cero en la columna de area construida, y ninguno de los registros restantes se encuantran clasificados como un estrato alto (de superior a cuatro), solo hay estrato rural, comercial e industrial, por lo que no podemos hacer el analisis en estrato alto

D. Relaciones entre Variables 9. Correlaciones: hallar las variables numericas que mas se correlacionene con el precio

numericas <- select_if(inmuebles, is.numeric) #creamos un data frame con solo variables numericas

correlaciones <- cor(numericas, use = "complete.obs")

correlaciones_con_precio <- sort(correlaciones["Precio", ], decreasing = TRUE)
correlaciones_con_precio
##          Precio Area Construida    Area Terreno          Codigo 
##       1.0000000       0.5621413       0.4701345      -0.3018968

con los resultados podemos conlcuir que el area construida influye mas que el area de terreno pues 0,56 es mayor que 0,47, ya que existe en la variable de area construida una correlación positiva moderada alta, lo que significa que a mayor área construida, mayor precio

10. Análisis multivariable: hallamos la relacion entre el precio con el estrato y el tipo de inmueble

library(ggplot2)

ggplot(inmuebles, aes(x = Estrato, y = Precio)) +
  geom_jitter(width = 0.2, alpha = 0.5, color = "darkblue") +
  facet_wrap(~ `Tipo de Inmueble`) +
  labs(title = "Relacion entre Precio y Estrato por Tipo de Inmueble",
       x = "Estrato",
       y = "Precio en pesos") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

Aqui podemos observar una relacion entre el precio, el inmuble y el estrato, teniendo los 19 tipos de inmuebles, por el eje X tenemos las 9 clasificaciones de estratos de la base de datos y por el eje Y una aproximacion de los precios.