Datos sobre el precio del alquiler en España

Vivienda
Alquiler
Inflación
España
Autor/a
Afiliación

Ángel Devesa Miralles

Universidad de Valencia

Fecha de publicación

1 de abril de 2026

Input

Se ha obtenido un conjunto de datos de alquiler de vivienda con información desagregada por municipio y año. Este fichero incluye variables administrativas y temáticas, como el código de provincia, el nombre de la provincia, el código postal, el nombre del municipio, el tipo de vivienda, el año de referencia y el valor observado. Por tanto, se trata de un conjunto de datos con interés espacio-temporal, ya que combina una dimensión territorial con una dimensión temporal.

Sin embargo, la base de datos original no incorpora coordenadas geográficas, por lo que no puede utilizarse directamente para representar la información sobre un mapa ni para llevar a cabo análisis espaciales. Para resolver esta limitación, se ha utilizado una segunda fuente de datos con localidades de España y sus coordenadas geográficas, concretamente latitud y longitud. Esta segunda base permite georreferenciar los municipios y convertir el conjunto final en un dataset espacial.

paquetes <- c("readr", "dplyr", "sf", "leaflet")

instalados <- rownames(installed.packages())

for (p in paquetes) {
  if (!(p %in% instalados)) {
    install.packages(p)
  }
}

library(readr)
library(dplyr)
library(sf)
library(leaflet)

url_alquiler <- "https://cdn.mivau.gob.es/portal-web-mivau/Datos_MIVAU/CSV/VDP001_01.csv"

url_localidades <- "https://gist.githubusercontent.com/soft2help/6f5fd0a2cb6d02da3e87fb61edcc4353/raw/e0db472ecf8fc084d8e38ca92769d31565815390/localidades.csv"

alquiler <- read.csv(url_alquiler, sep = ";")
localidades <- read.csv(url_localidades, header = F, sep = ";")

Descripción

Se detecta que el conjunto de datos de alquiler contiene información temática y temporal, pero no incluye coordenadas geográficas, por lo que no puede utilizarse directamente para análisis espacial. En consecuencia, es necesario complementarlo con una fuente externa que aporte latitud y longitud para cada municipio.

Además, se observa que la variable ELEMENTO contiene diferentes categorías, concretamente SUPERFICIE, PRECIO y VIVIENDA. Como el objetivo del trabajo es analizar el alquiler desde el punto de vista económico, solo interesa la categoría PRECIO, ya que es la que representa el valor monetario del alquiler. Las otras categorías contienen información útil en otros contextos, pero no son la variable principal de este análisis.

También se detecta que, al proceder de fuentes diferentes, los nombres de provincias y municipios pueden no coincidir exactamente en ambas tablas. Esto puede deberse a diferencias de mayúsculas y minúsculas, acentos, espacios o variantes en la escritura. Por ello, antes de realizar la unión, conviene normalizar los nombres para mejorar la correspondencia entre registros.

colnames(alquiler)
[1] "COD_PROVINCIA"    "PROVINCIA"        "COD_POSTAL"       "NOMBRE_MUNICIPIO"
[5] "ELEMENTO"         "TIPO_VIVIENDA"    "TIPO_MEDIDA"      "AÑO"             
[9] "VALOR"           
colnames(localidades)
[1] "V1" "V2" "V3" "V4" "V5" "V6" "V7" "V8" "V9"
summary(alquiler)
 COD_PROVINCIA    PROVINCIA           COD_POSTAL    NOMBRE_MUNICIPIO  
 Min.   : 2.00   Length:485097      Min.   : 2001   Length:485097     
 1st Qu.:12.00   Class :character   1st Qu.:12026   Class :character  
 Median :25.00   Mode  :character   Median :25057   Mode  :character  
 Mean   :25.22                      Mean   :25331                     
 3rd Qu.:39.00                      3rd Qu.:39046                     
 Max.   :52.00                      Max.   :52001                     
   ELEMENTO         TIPO_VIVIENDA      TIPO_MEDIDA             AÑO      
 Length:485097      Length:485097      Length:485097      Min.   :2011  
 Class :character   Class :character   Class :character   1st Qu.:2014  
 Mode  :character   Mode  :character   Mode  :character   Median :2018  
                                                          Mean   :2017  
                                                          3rd Qu.:2021  
                                                          Max.   :2023  
     VALOR         
 Min.   :     0.0  
 1st Qu.:    51.0  
 Median :   143.0  
 Mean   :   234.2  
 3rd Qu.:   309.0  
 Max.   :291225.0  
summary(localidades)
      V1                 V2                 V3                  V4       
 Length:8112        Length:8112        Length:8112        Min.   :27.73  
 Class :character   Class :character   Class :character   1st Qu.:39.87  
 Mode  :character   Mode  :character   Mode  :character   Median :41.19  
                                                          Mean   :40.73  
                                                          3rd Qu.:42.13  
                                                          Max.   :43.77  
       V5                V6               V7                V8         
 Min.   :-18.024   Min.   :   0.0   Min.   :      5   Min.   :      3  
 1st Qu.: -5.117   1st Qu.: 334.4   1st Qu.:    179   1st Qu.:     96  
 Median : -3.222   Median : 667.6   Median :    585   Median :    305  
 Mean   : -3.105   Mean   : 615.3   Mean   :   5763   Mean   :   2850  
 3rd Qu.: -1.121   3rd Qu.: 859.8   3rd Qu.:   2469   3rd Qu.:   1258  
 Max.   :  4.290   Max.   :1819.0   Max.   :3255944   Max.   :1532079  
       V9         
 Min.   :      2  
 1st Qu.:     84  
 Median :    279  
 Mean   :   2913  
 3rd Qu.:   1224  
 Max.   :1723865  

Tratamiento

Se ha realizado un proceso de preparación de datos orientado a construir un conjunto de datos espacial a partir de una base temática y otra geográfica. El tratamiento incluye el filtrado de la variable relevante, la selección de columnas necesarias, la limpieza básica de nombres, la extracción de coordenadas válidas, la unión entre ambas fuentes y la conversión final a objeto espacial.

1. Filtrado de la variable relevante

En primer lugar, se seleccionan únicamente los registros cuya categoría en la variable ELEMENTO es PRECIO, ya que estos representan el valor económico del alquiler. Además, se conservan solo las variables necesarias para el análisis.

alquiler_limpio <- alquiler %>%
  filter(ELEMENTO == "PRECIO") %>%
  select(
    COD_PROVINCIA,
    PROVINCIA,
    COD_POSTAL,
    NOMBRE_MUNICIPIO,
    TIPO_VIVIENDA,
    AÑO,
    VALOR
  )

2. Renombrado de columnas del dataset espacial

A continuación, se renombran las columnas de la base de localidades para que tengan nombres claros y homogéneos. Esto facilita tanto la lectura del código como la posterior unión con la base de alquiler.

localidades_limpio <- localidades %>%
  rename(
    "COMUNIDAD" = V1,
    "PROVINCIA" = V2,
    "NOMBRE_MUNICIPIO" = V3,
    "LATITUD" = V4,
    "LONGITUD" = V5,
    "ALTITUD" = V6,
    "TOTAL_HABITANTES" = V7,
    "HOMBRES" = V8,
    "MUJERES" = V9
  )

3. Corrección de nombres de provincias

Durante el proceso de integración de datos se detectaron inconsistencias en los nombres de las provincias entre ambas fuentes. En particular, algunas provincias aparecían con denominaciones bilingües (por ejemplo, “Alicante/Alacant”) o con formatos distintos (“Coruña, A” frente a “A Coruña”).

Para resolver este problema, se aplicó una recodificación manual de las provincias más conflictivas, con el objetivo de unificar los nombres y mejorar la correspondencia en la operación de unión (left_join). Este paso permitió aumentar significativamente el número de registros correctamente georreferenciados.

alquiler_limpio <- alquiler_limpio %>%
  mutate(
    PROVINCIA = case_when(
      PROVINCIA == "Coruña, A" ~ "A Coruña",
      PROVINCIA == "Palmas, Las" ~ "Las Palmas",
      PROVINCIA == "Balears, Illes" ~ "Illes Balears",
      PROVINCIA == "Rioja, La" ~ "La Rioja",
      PROVINCIA == "Valencia/Valéncia" ~ "València",
      TRUE ~ PROVINCIA
    )
  )

localidades_limpio <- localidades_limpio %>%
  mutate(
    PROVINCIA = case_when(
      PROVINCIA == "Alicante/Alacant" ~ "Alicante",
      PROVINCIA == "Valencia/València" ~ "València",
      PROVINCIA == "Guipúzcoa" ~ "Gipuzkoa",
      TRUE ~ PROVINCIA
    )
  )

4. Selección de coordenadas

Después, se extraen únicamente las variables necesarias de la base espacial: provincia, municipio, latitud y longitud. También se eliminan los registros que no tienen coordenadas válidas y, si existieran duplicados, se conserva una sola fila por combinación de provincia y municipio.

coordenadas <- localidades_limpio %>%
  select(PROVINCIA, NOMBRE_MUNICIPIO, LATITUD, LONGITUD) %>%
  filter(!is.na(LATITUD), !is.na(LONGITUD))

5. Unión de datasets

Una vez limpias ambas fuentes, se realiza una unión de tipo left_join() usando como claves PROVINCIA y NOMBRE_MUNICIPIO. De este modo, se mantienen todos los registros de la base de alquiler y se añaden las coordenadas cuando existe correspondencia.

dataset_final <- alquiler_limpio %>%
  left_join(coordenadas, by = c("PROVINCIA", "NOMBRE_MUNICIPIO"))

6. Eliminación de registros sin coordenadas

Tras la unión, puede ocurrir que algunos municipios no encuentren correspondencia exacta en la base de localidades. Por ello, se comprueba si hay registros que se han quedado sin latitud o longitud y se eliminan para poder crear correctamente el objeto espacial.

dataset_final <- dataset_final %>%
  filter(!is.na(LATITUD), !is.na(LONGITUD))

7. Conversión a objeto espacial

Finalmente, se transforma el dataset resultante en un objeto espacial con la librería sf, utilizando las columnas de longitud y latitud como coordenadas y el sistema de referencia EPSG:4326, que corresponde a coordenadas geográficas en WGS84.

dataset_sf <- st_as_sf(
  dataset_final,
  coords = c("LONGITUD", "LATITUD"),
  crs = 4326
)

Output

Se ha obtenido un conjunto de datos limpio, integrado y georreferenciado, que combina la información temática del alquiler con la localización geográfica de los municipios. El resultado final incorpora tanto la dimensión temporal, a través del año, como la dimensión espacial, mediante latitud y longitud, por lo que puede considerarse un dataset espacio-temporal.

Este conjunto de datos permite realizar análisis espaciales y espacio-temporales, así como su visualización en sistemas de información geográfica. Además, el resultado puede exportarse a formatos estándar para su reutilización posterior, por ejemplo en CSV para análisis tabular y en GeoJSON para representación cartográfica.

Además, se ha generado una visualización interactiva con leaflet en la que cada año se representa como una capa distinta. De este modo, el usuario puede seleccionar directamente en el mapa el año que desea visualizar, sin necesidad de modificar el código. Esto facilita la exploración temporal de los precios del alquiler en el conjunto del territorio español.

write.csv(dataset_final, "alquiler_georreferenciado.csv", row.names = FALSE)

st_write(dataset_sf, "alquiler_georreferenciado.geojson", delete_dsn = TRUE, quiet = TRUE)
# Años disponibles
anios <- sort(unique(dataset_sf$AÑO))

# Paleta de colores global
pal <- colorNumeric(
  palette = "YlOrRd",
  domain = dataset_sf$VALOR
)

# Crear mapa base
mapa <- leaflet() %>%
  addTiles()

# Añadir una capa por cada año
for (anio in anios) {
  
  datos_anio <- dataset_sf %>%
    filter(AÑO == anio)
  
  mapa <- mapa %>%
    addCircleMarkers(
      data = datos_anio,
      radius = 4,
      stroke = FALSE,
      fillOpacity = 0.75,
      color = ~pal(VALOR),
      popup = ~paste0(
        "<b>Municipio:</b> ", NOMBRE_MUNICIPIO, "<br>",
        "<b>Provincia:</b> ", PROVINCIA, "<br>",
        "<b>Año:</b> ", AÑO, "<br>",
        "<b>Valor:</b> ", VALOR
      ),
      group = as.character(anio)
    )
}

# Añadir leyenda y selector de capas
mapa %>%
  addLayersControl(
    baseGroups = as.character(anios),
    options = layersControlOptions(collapsed = FALSE)
  ) %>%
  addLegend(
    position = "bottomright",
    pal = pal,
    values = dataset_sf$VALOR,
    title = "Valor del alquiler"
  )

El/los fichero(s) generados con este procedimiento/técnica/metodología se puede(n) descargar de aquí.



Proyecto de Innovación Educativa Emergente (PIEE-3898312)