CARGA DE LA BASE DE DATOS Y ELIMINACIÓN DE DUPLICADOS

Primero, empezaremos cargando la base de datos de idealista 2018 y eliminando los valores duplicados que aparecen en esta, quedándonos con la vivienda de menor precio en el caso de que tengan el ASSETID repetido.

# Cargamos los datos

load('Valencia_Sale.rda')
Valencia_Sale <- as.data.frame(st_drop_geometry(Valencia_Sale)) # creamos el dataframe


# Eliminamos los duplicados

duplicados <- Valencia_Sale %>% group_by(ASSETID) %>% filter(n() > 1) %>% ungroup() # guardamos los duplicados
duplicados_buenos = duplicados %>% group_by(ASSETID) %>% filter(PRICE == min(PRICE)) %>% slice_head(n = 1) %>% ungroup() # de los duplicados, nos quedamos los de menor precio
Valencia_Sale <- anti_join(Valencia_Sale, duplicados, by = c("ASSETID", "PRICE")) # eliminamos los duplicados de la base de datos
Valencia_Sale <- rbind(Valencia_Sale, duplicados_buenos) # añadimos los duplicados buenos que nos queremos quedar


# Guradamos esto para la limpieza
summary_df <- as.data.frame(summary(Valencia_Sale)) 

summary(Valencia_Sale)
##                   ASSETID          PERIOD           PRICE        
##  A10000434603646497633:    1   Min.   :201803   Min.   :  20000  
##  A10001334147587469388:    1   1st Qu.:201803   1st Qu.:  97000  
##  A10002599312155392987:    1   Median :201809   Median : 148000  
##  A10002648121225460937:    1   Mean   :201808   Mean   : 195152  
##  A10002658173109908582:    1   3rd Qu.:201812   3rd Qu.: 228000  
##  A10003205125900904965:    1   Max.   :201812   Max.   :2772000  
##  (Other)              :27385                                     
##    UNITPRICE      CONSTRUCTEDAREA   ROOMNUMBER       BATHNUMBER    
##  Min.   : 480.7   Min.   : 24     Min.   : 0.000   Min.   : 0.000  
##  1st Qu.:1100.0   1st Qu.: 80     1st Qu.: 3.000   1st Qu.: 1.000  
##  Median :1511.1   Median :100     Median : 3.000   Median : 2.000  
##  Mean   :1692.5   Mean   :108     Mean   : 3.052   Mean   : 1.576  
##  3rd Qu.:2085.6   3rd Qu.:122     3rd Qu.: 4.000   3rd Qu.: 2.000  
##  Max.   :9421.8   Max.   :912     Max.   :81.000   Max.   :12.000  
##                                                                    
##    HASTERRACE        HASLIFT      HASAIRCONDITIONING   AMENITYID   
##  Min.   :0.0000   Min.   :0.000   Min.   :0.0000     Min.   :1.00  
##  1st Qu.:0.0000   1st Qu.:1.000   1st Qu.:0.0000     1st Qu.:3.00  
##  Median :0.0000   Median :1.000   Median :0.0000     Median :3.00  
##  Mean   :0.2504   Mean   :0.789   Mean   :0.4665     Mean   :2.77  
##  3rd Qu.:1.0000   3rd Qu.:1.000   3rd Qu.:1.0000     3rd Qu.:3.00  
##  Max.   :1.0000   Max.   :1.000   Max.   :1.0000     Max.   :3.00  
##                                                                    
##  HASPARKINGSPACE  ISPARKINGSPACEINCLUDEDINPRICE PARKINGSPACEPRICE 
##  Min.   :0.0000   Min.   :0.0000                Min.   :     1.0  
##  1st Qu.:0.0000   1st Qu.:0.0000                1st Qu.:     1.0  
##  Median :0.0000   Median :0.0000                Median :     1.0  
##  Mean   :0.1652   Mean   :0.1652                Mean   :   703.4  
##  3rd Qu.:0.0000   3rd Qu.:0.0000                3rd Qu.:     1.0  
##  Max.   :1.0000   Max.   :1.0000                Max.   :355001.0  
##                                                                   
##  HASNORTHORIENTATION HASSOUTHORIENTATION HASEASTORIENTATION HASWESTORIENTATION
##  Min.   :0.0000      Min.   :0.0000      Min.   :0.0000     Min.   :0.0000    
##  1st Qu.:0.0000      1st Qu.:0.0000      1st Qu.:0.0000     1st Qu.:0.0000    
##  Median :0.0000      Median :0.0000      Median :0.0000     Median :0.0000    
##  Mean   :0.1296      Mean   :0.1817      Mean   :0.2481     Mean   :0.1498    
##  3rd Qu.:0.0000      3rd Qu.:0.0000      3rd Qu.:0.0000     3rd Qu.:0.0000    
##  Max.   :1.0000      Max.   :1.0000      Max.   :1.0000     Max.   :1.0000    
##                                                                               
##    HASBOXROOM      HASWARDROBE     HASSWIMMINGPOOL     HASDOORMAN     
##  Min.   :0.0000   Min.   :0.0000   Min.   :0.00000   Min.   :0.00000  
##  1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.:0.00000   1st Qu.:0.00000  
##  Median :0.0000   Median :1.0000   Median :0.00000   Median :0.00000  
##  Mean   :0.1256   Mean   :0.5314   Mean   :0.06838   Mean   :0.04958  
##  3rd Qu.:0.0000   3rd Qu.:1.0000   3rd Qu.:0.00000   3rd Qu.:0.00000  
##  Max.   :1.0000   Max.   :1.0000   Max.   :1.00000   Max.   :1.00000  
##                                                                       
##    HASGARDEN          ISDUPLEX          ISSTUDIO         ISINTOPFLOOR    
##  Min.   :0.00000   Min.   :0.00000   Min.   :0.000000   Min.   :0.00000  
##  1st Qu.:0.00000   1st Qu.:0.00000   1st Qu.:0.000000   1st Qu.:0.00000  
##  Median :0.00000   Median :0.00000   Median :0.000000   Median :0.00000  
##  Mean   :0.05641   Mean   :0.01749   Mean   :0.005914   Mean   :0.01241  
##  3rd Qu.:0.00000   3rd Qu.:0.00000   3rd Qu.:0.000000   3rd Qu.:0.00000  
##  Max.   :1.00000   Max.   :1.00000   Max.   :1.000000   Max.   :1.00000  
##                                                                          
##  CONSTRUCTIONYEAR   FLOORCLEAN     FLATLOCATIONID  CADCONSTRUCTIONYEAR
##  Min.   :  11     Min.   :-1.000   Min.   :1.000   Min.   :1591       
##  1st Qu.:1962     1st Qu.: 2.000   1st Qu.:1.000   1st Qu.:1961       
##  Median :1970     Median : 3.000   Median :1.000   Median :1970       
##  Mean   :1970     Mean   : 3.551   Mean   :1.053   Mean   :1970       
##  3rd Qu.:1982     3rd Qu.: 5.000   3rd Qu.:1.000   3rd Qu.:1982       
##  Max.   :2020     Max.   :11.000   Max.   :2.000   Max.   :2018       
##  NA's   :10810    NA's   :1382     NA's   :4322                       
##  CADMAXBUILDINGFLOOR CADDWELLINGCOUNT CADASTRALQUALITYID BUILTTYPEID_1    
##  Min.   : 0.000      Min.   :  1.00   Min.   :0.000      Min.   :0.00000  
##  1st Qu.: 5.000      1st Qu.: 12.00   1st Qu.:4.000      1st Qu.:0.00000  
##  Median : 7.000      Median : 22.00   Median :5.000      Median :0.00000  
##  Mean   : 7.051      Mean   : 36.97   Mean   :5.361      Mean   :0.03238  
##  3rd Qu.: 8.000      3rd Qu.: 43.00   3rd Qu.:7.000      3rd Qu.:0.00000  
##  Max.   :33.000      Max.   :556.00   Max.   :9.000      Max.   :1.00000  
##                                                                           
##  BUILTTYPEID_2    BUILTTYPEID_3    DISTANCE_TO_CITY_CENTER DISTANCE_TO_METRO 
##  Min.   :0.0000   Min.   :0.0000   Min.   :0.003053        Min.   :0.003744  
##  1st Qu.:0.0000   1st Qu.:1.0000   1st Qu.:1.382520        1st Qu.:0.330851  
##  Median :0.0000   Median :1.0000   Median :2.131263        Median :0.539474  
##  Mean   :0.1293   Mean   :0.8383   Mean   :2.108405        Mean   :0.645145  
##  3rd Qu.:0.0000   3rd Qu.:1.0000   3rd Qu.:2.772409        3rd Qu.:0.870891  
##  Max.   :1.0000   Max.   :1.0000   Max.   :5.666819        Max.   :2.859185  
##                                                                              
##  DISTANCE_TO_BLASCO   LONGITUDE          LATITUDE    
##  Min.   :0.001828   Min.   :-0.4207   Min.   :39.44  
##  1st Qu.:1.190279   1st Qu.:-0.3894   1st Qu.:39.46  
##  Median :1.990819   Median :-0.3771   Median :39.47  
##  Mean   :2.054549   Mean   :-0.3747   Mean   :39.47  
##  3rd Qu.:2.849077   3rd Qu.:-0.3640   3rd Qu.:39.48  
##  Max.   :5.019537   Max.   :-0.3201   Max.   :39.50  
## 

Base ya cargada de IDEALISTA 2018 sin duplicados

Valencia_Sale


AED / Limpieza y Filtrado de la base

Realizamos un summary() de las variables para observar valores anómalos o posibles variables que debamos eliminar:

Por otra parte, hemos comparado si el FLOORCLEAN (nº de piso) concuerda con el nº de piso máx. registrado en el catastro. Se han encontrado 1028 pisos con un FLOORCLEAN > CADMAXBUILDINGFLOOR, no obstante, después de habernos informado sobre el tema, hemos llegado a las siguientes posibilidades:

Siguiendo esta línea hemos averiguado los anuncios con más baños que habitaciones (algo poco habitual), y separamos en 2 casos:

Por lo tanto dejaremos estas viviendas anunciadas en la base de datos.

Continuamos con pisos que no son estudios y tienen 0 habitaciones (contamos con 40). No los tendremos en cuenta en nuestro proyecto, ya que no nos aportan nada al proyecto y la mayoría son datos anómalos erróneos.

# Eliminamos CONSTRUCTIONYEAR
Valencia_Sale$CONSTRUCTIONYEAR <- NULL

# Eliminamos las viviendas de 1591 y 1671
Valencia_Sale <- Valencia_Sale[Valencia_Sale$CADCONSTRUCTIONYEAR != 1591 & Valencia_Sale$CADCONSTRUCTIONYEAR != 1671, ]

ggplot(Valencia_Sale, aes(x = as.factor(1), y = ROOMNUMBER)) +
  geom_boxplot(fill = "lightblue", color = "darkblue", notch = TRUE) +
  coord_flip() +  # Lo hace horizontal
  labs(title = "Boxplot del Número de Habitaciones",
       x = "",
       y = "Número de Habitaciones") +
  theme_minimal()
## Notch went outside hinges
## ℹ Do you want `notch = FALSE`?

ggplot(Valencia_Sale, aes(x = as.factor(1), y = BATHNUMBER)) +
  geom_boxplot(fill = "lightblue", color = "darkblue", notch = TRUE) +
  coord_flip() +  # Lo hace horizontal
  labs(title = "Boxplot del Número de Baños",
       x = "",
       y = "Número de Baños") +
  theme_minimal()
## Notch went outside hinges
## ℹ Do you want `notch = FALSE`?

# Eliminamos las viviendas con 81 habitaciones y 12 baños
Valencia_Sale <- Valencia_Sale[Valencia_Sale$ROOMNUMBER != 81, ]
Valencia_Sale <- Valencia_Sale[Valencia_Sale$BATHNUMBER != 12, ]

# Crear una variable categórica para los intervalos
Valencia_Sale$Precio_Categoria <- cut(Valencia_Sale$PARKINGSPACEPRICE, 
                                      breaks = c(0, 1, Inf), 
                                      labels = c("0 - 1€", "> 1€"),
                                      include.lowest = TRUE)

# Graficar el histograma con ggplot2
ggplot(Valencia_Sale, aes(x = Precio_Categoria)) +
  geom_bar(fill = "lightblue", color = "darkblue") +
  labs(title = "Histograma de Precios de Parking",
       x = "Intervalos de Precio (€)",
       y = "Frecuencia") +
  theme_minimal()

# Eliminamos PARKINGSPACEPRICE
Valencia_Sale$PARKINGSPACEPRICE <- NULL

# Eliminamos FLATLOCATIONID
Valencia_Sale$FLATLOCATIONID <- NULL


# viviendas donde FLOORCLEAN > CADMAXBUILDINGFLOOR
catastros_erroneos <- subset(Valencia_Sale, FLOORCLEAN > CADMAXBUILDINGFLOOR)
# viviendas donde BATHNUMBER > ROOMNUMBER y no son estudios
banyos_erroneos <- subset(Valencia_Sale, BATHNUMBER > ROOMNUMBER & ROOMNUMBER > 0)

no_estudios <- subset(Valencia_Sale, ISSTUDIO == 1 & ROOMNUMBER != 0)

# eliminamos las viviendas abiertas que no tienen habitaciones y no son estudios
pisos_abiertos <- subset(Valencia_Sale, ISSTUDIO != 1 & ROOMNUMBER == 0)
Valencia_Sale <- anti_join(Valencia_Sale, pisos_abiertos, by = c("ASSETID", "PRICE"))

descVal <- data.frame(
  "variable" = colnames(Valencia_Sale),
  "tipo" = c(rep("categorical", 2), rep("numerical", length(colnames(Valencia_Sale)) - 2)), 
  stringsAsFactors = FALSE
)

Valencia_Sale$RHabitacion_Banyo <- ifelse(Valencia_Sale$ROOMNUMBER == 0, 0, Valencia_Sale$BATHNUMBER / Valencia_Sale$ROOMNUMBER)

Una vez terminada la limpieza, realizaremos un AED más exhaustivo y preciso.

media_precios_2018 = mean(Valencia_Sale$PRICE)

mediana_precios_2018 = median(Valencia_Sale$PRICE)

summary(Valencia_Sale$PRICE)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   24000   97000  148000  194974  228000 2772000
# Creamos una nueva variable llamada SIZE, donde se clasificará cada vivienda en PEQUEÑA(20 - 70 m^2), MEDIANA(70 - 120 m^2) y GRANDE(+120 m^2) según los metros cuadrados en CONSTRUCTEDAREA. Convertimos también la variable a categórica
Valencia_Sale <- Valencia_Sale %>%
  mutate(SIZE = case_when(
    CONSTRUCTEDAREA >= 20 & CONSTRUCTEDAREA <= 70 ~ "Pequeña",
    CONSTRUCTEDAREA > 70 & CONSTRUCTEDAREA <= 120 ~ "Mediana",
    CONSTRUCTEDAREA > 120 ~ "Grande"
  ))  
Valencia_Sale$SIZE <- factor(Valencia_Sale$SIZE, 
                           levels = c("Pequeña", "Mediana", "Grande"),
                           ordered = TRUE)

# Ahora, calculamos la media y la mediana de precios por tamaño
precios_por_SIZE = Valencia_Sale %>%
  group_by(SIZE) %>%
  summarise(
    n = n(),  # cantidad de viviendas por categoría
    promedio_precio = mean(PRICE, na.rm = TRUE),
    mediana_precio = median(PRICE, na.rm = TRUE),
    min_precio = min(PRICE, na.rm = TRUE),
    max_precio = max(PRICE, na.rm = TRUE),
    sd_precio = sd(PRICE, na.rm = TRUE)
  )

barrios = read_delim("barris.csv", delim = ";", show_col_types = FALSE)
barrios$geometry <- geojson_sf(barrios$geo_shape)$geometry
barrios_sf <- st_as_sf(barrios, sf_column_name = "geometry", crs = 4326)
valencia_sf <- st_as_sf(Valencia_Sale, coords = c("LONGITUDE", "LATITUDE"), crs = 4326)
Valencia_Sale <- st_join(valencia_sf, barrios_sf[, c("Nombre")])
Valencia_Sale <- Valencia_Sale %>%
  rename(BARRIO = 'Nombre')
Valencia_Sale$BARRIO = as.factor(Valencia_Sale$BARRIO)


media_por_barrio = Valencia_Sale %>%
  group_by(BARRIO) %>%
  summarise(
    media_price = mean(PRICE, na.rm = TRUE),
    cantidad_pisos = n()
  )

Comprobaremos si existen pisos que no han tenido un barrio asignado.

sum(is.na(Valencia_Sale$BARRIO))   # ver el número de pisos faltantes, sin barrio asignado
## [1] 27

Observamos como contamos con 27 pisos que no cuentan con un barrio asignado. Es un valor pequeño de datos con faltantes, por ello decidimos eliminarlos del dataframe.

Valencia_Sale <- Valencia_Sale %>%
  filter(!is.na(BARRIO))
cor(Valencia_Sale$PRICE, Valencia_Sale$CONSTRUCTEDAREA, use = "complete.obs", method = "pearson")
## [1] 0.7756693
ggplot(Valencia_Sale, aes(x = SIZE, y = PRICE)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "lm", se = TRUE, color = "blue") +
  labs(title = "Relación entre metros cuadrados y precio",
       x = "Metros cuadrados",
       y = "Precio")
## `geom_smooth()` using formula = 'y ~ x'

El análisis de correlación entre el área construida (CONSTRUCTEDAREA) y el precio de venta (PRICE) de la vivienda muestra un coeficiente de Pearson de 0.776.

Esto podría indicar una fuerte relación positiva entre ambas variables. Esto sugiere que, en general, a mayor tamaño de construcción, mayor es el precio de venta de la vivienda.

Por otra parte, observando el scatter plot, podemos reforzar nuestras conclusiones.

El gráfico confirma que existe una relación positiva entre el tamaño de la vivienda y su precio: las viviendas más grandes tienden a alcanzar precios más elevados. Sin embargo, se observa también una mayor variabilidad en el precio entre las viviendas grandes, lo que sugiere que además del tamaño, otros factores (como ubicación, nºde baños, …) podrían llegar a influir sobre el precio de venta.