1 Introducción

En este trabajo se realizó un análisis exploratorio sobre una base de datos de propiedades inmobiliarias. El objetivo principal fue comprender el comportamiento de variables importantes como el precio, el área y el tipo de inmueble mediante herramientas estadísticas y gráficas.

Para desarrollar este análisis se utilizaron diferentes librerías de RStudio que permitieron limpiar, transformar y visualizar los datos de manera más organizada y entendible. Gracias a este proceso fue posible identificar patrones importantes, relaciones entre variables y posibles valores atípicos dentro de la información.

2 Objetivo del análisis

Con este análisis se buscó:

  • Limpiar y organizar la base de datos.
  • Detectar datos faltantes y duplicados.
  • Analizar cómo se distribuyen los precios de los inmuebles.
  • Comparar precios según el tipo de propiedad.
  • Encontrar relaciones entre variables como área y precio.
  • Generar gráficas y visualizaciones para interpretar mejor los datos.

3 Librerías utilizadas

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.2.0     ✔ readr     2.2.0
## ✔ forcats   1.0.1     ✔ stringr   1.6.0
## ✔ ggplot2   4.0.2     ✔ tibble    3.3.1
## ✔ lubridate 1.9.5     ✔ tidyr     1.3.2
## ✔ purrr     1.2.1     
## ── 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(reshape2)
## 
## Adjuntando el paquete: 'reshape2'
## 
## The following object is masked from 'package:tidyr':
## 
##     smiths
library(dplyr)
library(ggplot2)
library(readr)

En esta parte se cargaron las librerías necesarias para trabajar el análisis. Estas librerías nos permiten manipular datos, realizar filtros, crear gráficos y transformar la información de manera más sencilla.

Por ejemplo:

  • dplyr nos sirve para filtrar y organizar datos.
  • ggplot2 nos ayuda a construir gráficas.
  • reshape2 permite transformar estructuras de datos.
  • tidyverse agrupa herramientas muy útiles para análisis estadístico.

Gracias a estas librerías podemos realizar un análisis más completo y visual de la base de datos.

4 1. Carga de datos

datos <- read.csv("C:/Users/Isaac Mendoza/Downloads/propiedad.csv")

Aquí cargamos la base de datos principal llamada propiedad.csv.

Utilizamos el código read.csv() porque este nos permite importar archivos CSV al entorno de trabajo de RStudio. Esto nos sirve para comenzar a trabajar la información contenida en la base de datos.

Al cargar los datos correctamente podemos posteriormente analizarlos, limpiarlos y generar gráficos estadísticos.

5 Limpieza de nombres

names(datos) <- tolower(names(datos))
names(datos) <- gsub(" ", "_", names(datos))

En esta parte limpiamos los nombres de las columnas.

Usamos tolower() para convertir todos los nombres a minúsculas y evitar errores al momento de escribir variables.

También usamos gsub() para reemplazar espacios por guiones bajos _, ya que los espacios pueden generar problemas en algunos códigos.

Esto nos ayuda a trabajar de manera más organizada y evita errores futuros durante el análisis.

6 2. Creación de datos limpios

propiedad2 <- datos

Aquí creamos una copia de la base original.

Esto se hizo para mantener protegida la base de datos inicial y poder trabajar sobre una nueva versión limpia llamada propiedad2.

Esto nos sirve para hacer modificaciones sin alterar los datos originales.

6.1 Eliminación de valores faltantes

propiedad2 <- na.omit(propiedad2)

Utilizamos na.omit() para eliminar filas que contienen valores faltantes.

Esto es importante porque los datos vacíos pueden afectar los resultados estadísticos y generar errores en gráficas o cálculos.

Gracias a este proceso obtenemos una base de datos más limpia y precisa.

6.2 Eliminación de duplicados

propiedad2 <- propiedad2[!duplicated(propiedad2), ]

Con este código eliminamos registros repetidos dentro de la base de datos.

Esto nos sirve para evitar información duplicada que pueda alterar análisis como promedios, correlaciones o gráficos.

Al final obtenemos una base de datos más confiable.

7 3. Exploración inicial de los datos

str(propiedad2)
## 'data.frame':    583 obs. of  21 variables:
##  $ conjunto          : chr  "Santa Mónica" " Chicó Milano 101" "Portal del Belmira " "Carmel Reservado " ...
##  $ administración    : int  532000 0 811893 400200 270000 211000 226000 529000 130000 453000 ...
##  $ estrato           : int  4 6 4 4 4 3 4 4 3 5 ...
##  $ antiguedad        : int  37 7 14 11 20 19 24 30 9 8 ...
##  $ remodelado        : chr  "Si" "Si" "Si" "Si" ...
##  $ área              : num  86 77 109 76 105 67 72 77 59 54 ...
##  $ habitaciones      : int  1 1 3 3 4 3 3 2 3 1 ...
##  $ baños             : int  1 2 4 2 2 2 2 2 2 2 ...
##  $ garajes           : int  1 2 2 1 1 1 1 1 1 1 ...
##  $ elevadores        : int  1 1 1 2 0 0 2 1 1 1 ...
##  $ tipo_de_inmueble  : chr  "Apartamento" "Apartamento" "Apartamento" "Apartamento" ...
##  $ deposito          : int  0 1 0 0 1 0 1 0 0 1 ...
##  $ porteria          : chr  "24 hrs" "24 hrs" "24 hrs" "24 hrs" ...
##  $ zona_de_lavanderia: chr  "No Tiene" "No Tiene" "No Tiene" "No Tiene" ...
##  $ gas               : chr  "Si" "Si" "Si" "Si" ...
##  $ parqueadero       : chr  "No" "Si" "Si" "Si" ...
##  $ precio            : num  3.14e+08 4.40e+08 4.95e+08 4.42e+08 3.87e+08 ...
##  $ direccion         : chr  "Avenida Carrera 3 # 59-65" "Carrera 12 #101A-18" "Calle 146 #7F-54" "KR 54 152A 35" ...
##  $ nombre            : chr  "Santa Mónica" "Chicó Milano 101" "Portal del Belmira" "Carmel Reservado" ...
##  $ descripcion       : chr  "Apartamento en venta de 86 m2, con vista exterior, ubicado en un 1er piso (Apto 104), acceso por escaleras, par"| __truncated__ "Apartamento en venta de 77m2, con vista interior, ubicado en un 4to piso (Apto 402), acceso por ascensor, parqu"| __truncated__ "Apartamento en venta de 109 m2, con vista Interior, ubicado en un 2do piso (Apto 204), acceso por ascensor, par"| __truncated__ "Apartamento en venta de 76m2, con vista exterior, ubicado en un 13avo piso (Apto 1302), acceso por escaleras y "| __truncated__ ...
##  $ barrio            : chr  "PARDO RUBIO" "USAQUEN" "LOS CEDROS" "EL PRADO" ...
##  - attr(*, "na.action")= 'omit' Named int [1:2] 141 180
##   ..- attr(*, "names")= chr [1:2] "141" "180"
summary(propiedad2)
##    conjunto         administración       estrato        antiguedad   
##  Length:583         Min.   :      0   Min.   :1.000   Min.   : 0.00  
##  Class :character   1st Qu.:  75000   1st Qu.:2.000   1st Qu.: 7.00  
##  Mode  :character   Median : 136000   Median :3.000   Median :13.00  
##                     Mean   : 206175   Mean   :3.129   Mean   :15.16  
##                     3rd Qu.: 272550   3rd Qu.:4.000   3rd Qu.:21.00  
##                     Max.   :1976535   Max.   :6.000   Max.   :48.00  
##   remodelado             área        habitaciones       baños      
##  Length:583         Min.   : 26.0   Min.   :1.000   Min.   :0.000  
##  Class :character   1st Qu.: 47.0   1st Qu.:2.000   1st Qu.:1.000  
##  Mode  :character   Median : 55.0   Median :3.000   Median :2.000  
##                     Mean   : 60.4   Mean   :2.592   Mean   :1.647  
##                     3rd Qu.: 70.0   3rd Qu.:3.000   3rd Qu.:2.000  
##                     Max.   :207.0   Max.   :8.000   Max.   :4.000  
##     garajes         elevadores     tipo_de_inmueble      deposito     
##  Min.   :0.0000   Min.   :0.0000   Length:583         Min.   :0.0000  
##  1st Qu.:0.0000   1st Qu.:0.0000   Class :character   1st Qu.:0.0000  
##  Median :0.0000   Median :0.0000   Mode  :character   Median :0.0000  
##  Mean   :0.4803   Mean   :0.5695                      Mean   :0.1904  
##  3rd Qu.:1.0000   3rd Qu.:1.0000                      3rd Qu.:0.0000  
##  Max.   :3.0000   Max.   :4.0000                      Max.   :1.0000  
##    porteria         zona_de_lavanderia     gas            parqueadero       
##  Length:583         Length:583         Length:583         Length:583        
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##      precio           direccion            nombre          descripcion       
##  Min.   :8.500e+07   Length:583         Length:583         Length:583        
##  1st Qu.:1.520e+08   Class :character   Class :character   Class :character  
##  Median :2.171e+08   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :2.603e+08                                                           
##  3rd Qu.:3.520e+08                                                           
##  Max.   :1.530e+09                                                           
##     barrio         
##  Length:583        
##  Class :character  
##  Mode  :character  
##                    
##                    
## 

Aquí realizamos una exploración inicial de la base de datos.

La función str() nos permite observar:

  • tipos de variables
  • cantidad de datos
  • estructura general del dataset

Mientras que summary() genera un resumen estadístico con:

  • medias
  • medianas
  • mínimos
  • máximos
  • cuartiles

Esto nos ayuda a entender mejor cómo está organizada la información antes de analizarla.

8 4. Tratamiento de valores NA

colSums(is.na(datos))
##           conjunto     administración            estrato         antiguedad 
##                  0                  0                  2                  0 
##         remodelado               área       habitaciones              baños 
##                  0                  0                  0                  0 
##            garajes         elevadores   tipo_de_inmueble           deposito 
##                  0                  0                  0                  0 
##           porteria zona_de_lavanderia                gas        parqueadero 
##                  0                  0                  0                  0 
##             precio          direccion             nombre        descripcion 
##                  0                  0                  0                  0 
##             barrio 
##                  0

En esta parte identificamos cuántos valores faltantes existen en cada variable.

Usamos is.na() para detectar datos vacíos y colSums() para contarlos.

Esto nos sirve para conocer qué tan limpia está la base de datos y decidir cómo tratar los datos faltantes.

if("precio" %in% names(datos)){
  datos$precio[is.na(datos$precio)] <- median(datos$precio, na.rm = TRUE)
}

Aquí reemplazamos los valores faltantes de la variable precio utilizando la mediana.

Usamos la mediana porque es una medida menos sensible a valores extremos.

Esto nos permite conservar información importante sin eliminar demasiados registros.

9 5. Histograma por tipo de inmueble

ggplot(propiedad2, aes(x = precio)) +
  geom_histogram() +
  facet_wrap(~tipo_de_inmueble) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))
## `stat_bin()` using `bins = 30`. Pick better value `binwidth`.

En esta sección construimos histogramas de precios según el tipo de inmueble.

Usamos ggplot() para generar gráficas y facet_wrap() para dividir la visualización por categorías.

Esto nos ayuda a comparar cómo se comportan los precios dependiendo del tipo de propiedad.

Gracias a esta gráfica podemos identificar diferencias importantes entre categorías.

10 6. Filtrado de propiedades

propiedad_filtrada <- propiedad2 %>%
  filter(precio < 300000000)

head(propiedad_filtrada)

Aquí filtramos propiedades con precios menores a 300 millones.

Usamos filter() porque nos permite seleccionar información específica dentro de la base de datos.

Esto sirve para enfocarnos únicamente en propiedades de menor valor económico y facilitar análisis más concretos.

La función head() muestra las primeras filas del resultado para verificar que el filtro se aplicó correctamente.

11 7. Boxplot de precios

if(all(c("tipo_de_inmueble","precio") %in% names(propiedad2))){
  ggplot(propiedad2, aes(x = tipo_de_inmueble, y = precio)) +
    geom_boxplot()
}

En esta parte construimos un boxplot o diagrama de cajas.

Este gráfico nos sirve para comparar la distribución de precios entre categorías y detectar valores atípicos.

Gracias a este análisis podemos observar:

  • medianas
  • dispersión
  • posibles datos extremos

12 8. Gráfico de densidad

if(all(c("tipo_de_inmueble","precio") %in% names(propiedad2))){
  ggplot(propiedad2, aes(x = precio, fill = tipo_de_inmueble)) +
    geom_density(alpha = 0.5)
}

Aquí utilizamos gráficos de densidad para analizar cómo se distribuyen los precios.

Este tipo de gráfico nos permite observar concentraciones y patrones dentro de cada categoría.

Nos sirve para comparar visualmente diferentes tipos de inmuebles y detectar tendencias.

13 9. Histograma general del precio

if("precio" %in% names(propiedad2)){
  ggplot(propiedad2, aes(x = precio)) +
    geom_histogram() +
    ggtitle("Distribución del precio")
}
## `stat_bin()` using `bins = 30`. Pick better value `binwidth`.

Este histograma muestra la distribución general de precios.

Con esta gráfica podemos identificar:

  • concentración de valores
  • rangos más frecuentes
  • posibles valores extremos

Esto nos ayuda a comprender mejor el comportamiento general de la variable precio.

14 10. Histograma filtrado

ggplot(propiedad2 %>% filter(precio < 300000000), aes(x = precio/1000000)) +
  geom_histogram() +
  ggtitle("Precio menor a 300 millones") +
  xlab("Precio en millones")
## `stat_bin()` using `bins = 30`. Pick better value `binwidth`.

Aquí construimos un histograma únicamente con propiedades menores a 300 millones.

Esto nos permite visualizar de manera más clara los inmuebles económicos y analizar mejor ese segmento específico.

15 11. Distribución de precios

ggplot(propiedad2, aes(x = precio)) +
  geom_density()

Esta gráfica de densidad permite analizar la forma de distribución de los precios.

Nos ayuda a identificar si los datos presentan concentración, dispersión o sesgos.

16 12. Boxplot del área

if("área" %in% names(propiedad2)){
  ggplot(propiedad2, aes(y = área)) +
    geom_boxplot()
}

Aquí analizamos la variable área mediante un boxplot.

Esto nos sirve para detectar posibles valores atípicos en el tamaño de las propiedades.

17 13. Relación entre área y precio

if(all(c("área","precio") %in% names(propiedad2))){
  ggplot(propiedad2, aes(x = área, y = precio)) +
    geom_point()
}

En esta parte construimos un gráfico de dispersión.

Este gráfico nos ayuda a observar si existe relación entre el área y el precio de las propiedades.

Gracias a esto podemos identificar tendencias entre ambas variables.

18 14. Correlación entre variables

if(all(c("área","precio") %in% names(propiedad2))){
  cor(propiedad2$área, propiedad2$precio, use = "complete.obs")
}
## [1] 0.8697718

Aquí calculamos la correlación entre área y precio.

La correlación nos indica qué tan fuerte es la relación entre dos variables numéricas.

Esto nos permite saber si al aumentar el área también aumenta el precio.

19 15. Correlación visual

if(all(c("área","precio") %in% names(propiedad2))){
  ggplot(propiedad2, aes(x = área, y = precio)) +
    geom_point() +
    geom_smooth(method = "lm")
}
## `geom_smooth()` using formula = 'y ~ x'

Aquí agregamos una línea de tendencia al gráfico de dispersión.

Esto nos sirve para visualizar de forma más clara la relación entre las variables.

La línea nos ayuda a interpretar si existe una tendencia positiva o negativa.

20 16. Variables numéricas

numericas <- propiedad2 %>%
  select_if(is.numeric)

Aquí seleccionamos únicamente variables numéricas.

Esto se hizo porque las correlaciones solo pueden calcularse entre variables numéricas.

21 17. Matriz de correlación

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

Con este código generamos una matriz de correlación.

Esto nos permite analizar la relación entre todas las variables numéricas al mismo tiempo.

22 18. Conversión a formato largo

cor_long <- melt(matriz_cor)

Aquí transformamos la matriz de correlación a formato largo.

Esto nos sirve para facilitar la construcción del heatmap.

23 19. Heatmap de correlaciones

ggplot(cor_long, aes(Var1, Var2, fill = value)) +
  geom_tile(color = "white") +
  geom_text(aes(label = round(value, 2)), size = 3) +
  scale_fill_gradient2(low = "blue", mid = "white", high = "red", midpoint = 0) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

En esta parte construimos un mapa de calor de correlaciones.

Este gráfico nos ayuda a identificar visualmente relaciones fuertes y débiles entre variables.

Los colores representan el nivel de correlación:

  • rojo = correlación positiva fuerte
  • azul = correlación negativa
  • blanco = poca relación

24 Procesos realizados

Durante el desarrollo del trabajo se realizaron los siguientes procesos:

  1. Importación de la base de datos.
  2. Limpieza de nombres y organización de variables.
  3. Eliminación de valores faltantes y duplicados.
  4. Exploración estadística.
  5. Construcción de histogramas y boxplots.
  6. Análisis de densidad.
  7. Estudio de correlaciones.
  8. Construcción de heatmaps.

25 Resultados obtenidos

A través del análisis realizado se logró:

  • Organizar correctamente la base de datos.
  • Identificar patrones importantes en los precios.
  • Comparar tipos de inmuebles.
  • Detectar valores atípicos.
  • Encontrar relaciones entre variables numéricas.
  • Generar visualizaciones útiles para interpretar la información.

26 Conclusión

El análisis exploratorio permitió comprender mejor el comportamiento de la base de datos inmobiliaria. Gracias a los procesos de limpieza, filtrado y visualización fue posible identificar patrones relevantes en variables como precio, área y tipo de inmueble.

Además, las gráficas y análisis estadísticos ayudaron a interpretar mejor la información y facilitar futuras investigaciones o análisis más avanzados.

```

26.1 Including Plots

You can also embed plots, for example:

Note that the echo = FALSE parameter was added to the code chunk to prevent printing of the R code that generated the plot.