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
##
Valencia_Sale
Realizamos un summary() de las variables para observar
valores anómalos o posibles variables que debamos eliminar:
Cabe resaltar que solamente encontramos faltantes en la v.a: CONSTRUCTIONYEAR, FLOORCLEAN y FLATLOCATIONID
Eliminamos CONSTRUCTIONYEAR ya que contiene muchos valores faltantes y atípicos. Además no es una variable importante ya que CADCONSTRUCTIONYEAR realiza la misma función y de forma más correcta.
En esta última variable vemos dos valores anómalos que son 1591 y 1671 (unas fechas demasiado antiguas), que podemos eliminar sin problema.
Hemos encontrado una vivienda con 81 habitaciones, algo imposible para los 90m^2 que posee. Por esta razón, hemos decidido eliminarla.
Después de eliminar la vivienda anómala, hemos observado dos viviendas con 15 habitaciones, pero estas parecen correctas debido a que su precio y m^2 es razonablemente alto.
Hemos identificado una vivienda con 8 habitaciones y 12 baños, valor que consideramos anómalo por lo que eliminamos la fila.
Eliminamos también la variable PARKINGSPACEPRICE dado que no nos aporta información relevante y contiene muchos datos anómalos (precios de 1€). A continuación, mostramos mediante la librería ggplot2 en R, un histograma con la frecuencia de precios de Parking divididos en 2 intervalos (de 0 a 1€ y más de 1€). Como bien apreciamos, la frecuencia de Parkings con el precio de 1€ es enorme, algo que no tiene sentido alguno.
Eliminamos la variable FLATLOCATIONID ya que cuenta con más de 4000 datos faltantes, un número considerable, y no es una variable muy relevante para el análisis.
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:
La posible existencia de entreplantas o plantas técnicas: En algunos edificios, hay plantas intermedias (como entresuelos, plantas técnicas o plantas de instalaciones) que no se cuentan en la numeración habitual pero sí en el Catastro.
Modificaciones en la estructura del edificio: Si se han hecho reformas o ampliaciones, la numeración interna del edificio pudo cambiar, pero el Catastro puede reflejar la estructura original.
Siguiendo esta línea hemos averiguado los anuncios con más baños que habitaciones (algo poco habitual), y separamos en 2 casos:
Los pisos con 0 habitaciones y baños, son estudios, es totalmente normal que tenga baño/s.
Habiendo observado las viviendas con más baños que viviendas, hemos apreciado que la mayoría tienen un precio muy elevado, y esto justificaría el mayor nº de baños. Muchas casas grandes o de lujo tienen un baño privado en cada habitación (en suite), más baños adicionales para visitas o zonas comunes –> Ejemplo: Una mansión con 3 dormitorios y 5 baños (baños en cada habitación, uno de servicio y uno de cortesía).
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.
Tamaño pequeño: La mayoría de los precios son “bajos”, solamente uno de ellos supera los 500.000 €.
Tamaño mediano: Los precios tienden a ser más altos que los de las viviendas pequeñas, pero siguen concentrados en precios relativamente accesibles, con algunos valores atípicos caros.
Tamaño grande: Se observa una gran dispersión de precios, incluyendo las viviendas más caras del conjunto, algunas llegando a superar la barrera de los 2 millones de euros.
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.