Mercado de la vivienda

12/12/24

1. Introducción

  • El mercado de la vivienda es clave para la estabilidad económica y financiera en Europa.

  • El trabajo analiza España, Francia y Alemania desde una perspectiva comparada.

  • Se estudian factores demográficos, precios, construcción y relación con los ingresos.

  • El objetivo es identificar diferencias, tendencias y problemas de asequibilidad.

  • Se busca entender cómo los cambios económicos y sociales afectan al acceso a la vivienda.

Código

#Cargamos las librerías que vamos a usar
library(tidyverse)
library(eurostat)
library(sf)
library(rnaturalearth)
library(knitr)
library(ggplot2)
library(dplyr)
library(plotly)
library(countrycode)
library(sf)
library(rio)
library(extrafont)
library(patchwork)
library(leaflet)
library(htmltools)
library(RColorBrewer)
library(giscoR)
library(gt)

#seleccionamos los países que vamos a comparar
codigos_paises <- c(
  "ES", # España
  "FR", # Francia
  "DE" # Alemania
)

codigos_paises_00 <- c(
  "EU27_2020",
  "ES", # España
  "FR" # Francia
)

2. Factores demograficos

2.1. Edad de la población

  • Se compara la estructura por edades en 2000 y 2024.
  • Se observa un envejecimiento poblacional en los tres países.
  • Implica una gran transferencia de viviendas heredadas que aumenta la oferta en el mercado.
  • Amplifica la desigualdad.
Código
options(eurostat_cache = TRUE)

df_orig <- get_eurostat("demo_r_pjanaggr3", time_format = "raw", keepFlags = TRUE)
#> 
indexed 0B in  0s, 0B/s
indexed 2.15GB in  0s, 2.15GB/s
                                                                              

df <- df_orig %>%
  select(geo, TIME_PERIOD, age, values, sex) %>% 
  rename(
    year = TIME_PERIOD,
    age_code = age,
    poblacion = values
  ) %>%
  filter(sex == "T") 

df_ok <- df %>%
  filter(
    geo %in% c("ES","DE","FR"),
    year %in% c(2000,2024),
    age_code %in% c("Y_LT15","Y15-64","Y_GE65")
  ) %>%
  group_by(geo, year, age_code) %>%
  summarise(
    poblacion = sum(poblacion, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  mutate(poblacion_signed = ifelse(year==2000, -poblacion, poblacion)) %>%
  mutate(age_label = case_when(
    age_code == "Y_LT15" ~ "0–14 años",
    age_code == "Y15-64" ~ "15–64 años",
    age_code == "Y_GE65" ~ "65 años y más"
  ))

df_ok$age_label <- factor(df_ok$age_label, levels = c("0–14 años","15–64 años","65 años y más"))

df_ok$geo <- factor(df_ok$geo, levels = c("FR","DE","ES"), labels = c("Francia","Alemania","España"))

pop_max <- max(abs(df_ok$poblacion_signed), na.rm = TRUE)

ggplot(df_ok, aes(x = poblacion_signed, y = age_label, fill = factor(year))) +
  geom_col(width = 0.6) +
  scale_x_continuous(
    limits = c(-pop_max, pop_max),
    breaks = seq(-60000000, 60000000, by = 30000000),
    labels = function(x) {
      paste0(
        round(abs(x) / 1000000, 0)
      )
    },
    name = "Población total (millones)"
  ) +
  scale_fill_manual(values = c("2000"="#A2B5CD","2024"="#8B7D6B")) +
  facet_wrap(~geo) +
  labs(
    title="Pirámide poblacional comparativa: 2000 vs 2024",
    y="Grupo de edad",
    fill="Año",
    caption="Fuente: Eurostat (demo_r_pjanaggr3)"
  ) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 9),
    strip.text = element_text(face = "bold")
  )

2.2. Tamaño de los hogares

En segundo lugar, analizamos el tamaño de los hogares.

Observamos en el gráfico una reducción de manera agregada en el tamaño de los hogares.

  • Si comparamos los países, vemos que donde más se reduce es en España, seguido de Francia y después de Alemania.

  • El tamaño medio del hogar disminuye en los tres países. Esto incrementa la presión sobre la demanda y los precios de la vivienda.

  • Hogares más pequeños implican más viviendas necesarias para la misma población.

Código
#- segundo gráfico
my_table_HHS <- "ilc_lvph01"

df_HHS <- get_eurostat(my_table_HHS, time_format = 'raw', keepFlags = TRUE)     
#> 
indexed 0B in  0s, 0B/s
indexed 2.15GB in  0s, 2.15GB/s
                                                                              

codigos_paises <- c(
  "ES", # España
  "FR", # Francia
  "DE") # Ale

df_paises_HHS <-  df_HHS |> 
  filter (geo %in% codigos_paises) |> 
  filter(TIME_PERIOD %in% c("2005", "2015", "2024"))

p1 <- ggplot(df_paises_HHS, aes(x = TIME_PERIOD, y = values, fill = geo)) + 
  geom_col() + 
  labs(title = "Tamaño promedio hogares", 
       x = "Año",
       y = "Valores", 
       fill = "País", 
       caption = "Fuente: Eurostat") + 
  theme(plot.title = element_text(
          family = "sans",
          size = 12,
          face = "plain"), 
        axis.text.x = element_text(size = 8),
        axis.text.y = element_text(size = 8))

my_pal = c("gray50","#36648B", "#A2B5CD")
           
p1 + scale_fill_manual(values = my_pal)

3. Mercado de la vivienda

3.1. Volumen de la producción en la construcción

  • España muestra alta volatilidad y sensibilidad a crisis económicas (especialmente en 2020).

  • Francia presenta una tendencia decreciente desde 2017, con un breve repunte en 2021.

  • La UE muestra una evolución más estable al ser un promedio.

  • La construcción responde fuertemente a shocks macroeconómicos.

Código
my_table_2 <- "sts_copr_a"        #- seleccioné la tabla: "Distribution of population by housing cost burden and degree of urbanisation"

df_09 <- get_eurostat(my_table_2, time_format = 'raw', keepFlags = TRUE)
#> 
indexed 0B in  0s, 0B/s
indexed 2.15GB in  0s, 2.15GB/s
                                                                              


df_10 <- df_09 %>%
  filter(TIME_PERIOD >= 2015) %>% 
  filter(freq == "A") %>%
  filter(s_adj == "CA") %>% 
  filter(nace_r2 == "F41") %>% 
  filter(geo %in% codigos_paises_00) %>%
  filter(
    unit == "PCH_SM", 
    !is.na(values)    
  ) %>% 
  mutate(TIME_PERIOD = as.integer(as.numeric(TIME_PERIOD)))


ggplot(data = df_10, aes(x = TIME_PERIOD, y = values)) +
  geom_line(aes(group = geo), color = "#A2B5CD", linewidth = 0.7, alpha = 0.5) +
  geom_line(data= df_10 %>% filter(geo == "ES"), aes(group = geo), color = "#36648B", linewidth = 1) +
  geom_line(data= df_10 %>% filter(geo == "EU27_2020"), aes(group = geo), color = "#8B2323", linewidth = 1) +
  scale_x_continuous(breaks = seq(min(df_10$TIME_PERIOD), max(df_10$TIME_PERIOD), 1)) +
  scale_y_continuous(labels = function(x) paste0(x, "%")) +
  labs(
    title = "Volumen de la producción en la construcción de edificios residenciales y \nno residenciales",
    subtitle = "Cambio porcentual respecto al mismo periodo del año anterior ",
    x = "Año",
    y = "variación interanual",
    caption = "Fuente: Eurostat") +
  annotate("text", x = 2024.3, y = -2.5, label = "UE", color = "#8B2323", size = 3) + 
  annotate("text", x = 2024.3, y = 2.7, label = "España", color = "#36648B", size = 3) + 
  annotate("text", x = 2024.3, y = -7, label = "Francia", color = "#A2B5CD", size = 3) +
  theme_minimal() +
  theme(
    panel.grid.major.x = element_blank(), 
    panel.grid.minor.x = element_blank(), 
    axis.text.x = element_text(angle = 0, hjust = 1),
    plot.title = element_text(
      family = "sans",
      size = 12,
      face = "bold"))

3.2. Alquileres reales pagados por los inquilinos

  • Los alquileres aumentan en todos los países desde 2015.

  • España presenta el mayor crecimiento desde 2019.

  • A partir de 2022 se acelera el crecimiento en todos los territorios.

  • Esto refleja un deterioro general de la asequibilidad del alquiler.

Código
my_table <- "prc_hicp_midx"         

label_eurostat_tables(my_table)     
#> [1] "HICP - monthly data (index)"

df <- get_eurostat(my_table, time_format = 'raw', keepFlags = TRUE)
#> 
indexed 0B in  0s, 0B/s
indexed 26.74MB in  0s, 132.84MB/s
indexed 26.87MB in  0s, 132.43MB/s
indexed 27.00MB in  0s, 132.52MB/s
indexed 27.13MB in  0s, 132.54MB/s
indexed 27.26MB in  0s, 131.92MB/s
indexed 27.39MB in  0s, 131.81MB/s
indexed 27.52MB in  0s, 127.76MB/s
indexed 27.66MB in  0s, 127.75MB/s
indexed 27.79MB in  0s, 127.69MB/s
indexed 27.92MB in  0s, 127.74MB/s
indexed 28.05MB in  0s, 127.85MB/s
indexed 28.18MB in  0s, 127.64MB/s
indexed 28.31MB in  0s, 127.59MB/s
indexed 28.44MB in  0s, 127.71MB/s
indexed 28.57MB in  0s, 127.87MB/s
indexed 28.70MB in  0s, 127.89MB/s
indexed 28.84MB in  0s, 127.85MB/s
indexed 28.97MB in  0s, 127.98MB/s
indexed 29.10MB in  0s, 127.79MB/s
indexed 29.23MB in  0s, 127.81MB/s
indexed 29.36MB in  0s, 127.85MB/s
indexed 29.49MB in  0s, 127.90MB/s
indexed 29.62MB in  0s, 127.92MB/s
indexed 29.75MB in  0s, 128.07MB/s
indexed 29.88MB in  0s, 128.04MB/s
indexed 30.02MB in  0s, 128.01MB/s
indexed 30.15MB in  0s, 127.63MB/s
indexed 30.28MB in  0s, 127.45MB/s
indexed 30.41MB in  0s, 127.33MB/s
indexed 30.54MB in  0s, 127.37MB/s
indexed 30.67MB in  0s, 127.37MB/s
indexed 30.80MB in  0s, 127.45MB/s
indexed 30.93MB in  0s, 127.55MB/s
indexed 31.06MB in  0s, 127.65MB/s
indexed 31.19MB in  0s, 127.77MB/s
indexed 31.33MB in  0s, 127.78MB/s
indexed 31.46MB in  0s, 127.76MB/s
indexed 31.59MB in  0s, 127.73MB/s
indexed 31.72MB in  0s, 127.68MB/s
indexed 31.85MB in  0s, 127.78MB/s
indexed 31.98MB in  0s, 127.46MB/s
indexed 32.11MB in  0s, 127.41MB/s
indexed 32.24MB in  0s, 127.42MB/s
indexed 32.37MB in  0s, 127.44MB/s
indexed 32.51MB in  0s, 127.32MB/s
indexed 32.64MB in  0s, 127.37MB/s
indexed 32.77MB in  0s, 127.38MB/s
indexed 32.90MB in  0s, 127.32MB/s
indexed 33.03MB in  0s, 127.34MB/s
indexed 33.16MB in  0s, 127.28MB/s
indexed 33.29MB in  0s, 127.40MB/s
indexed 33.42MB in  0s, 127.49MB/s
indexed 33.55MB in  0s, 127.46MB/s
indexed 33.69MB in  0s, 127.47MB/s
indexed 33.82MB in  0s, 127.40MB/s
indexed 33.95MB in  0s, 127.46MB/s
indexed 34.08MB in  0s, 127.26MB/s
indexed 34.21MB in  0s, 127.40MB/s
indexed 34.34MB in  0s, 127.41MB/s
indexed 34.47MB in  0s, 127.34MB/s
indexed 34.60MB in  0s, 127.41MB/s
indexed 34.73MB in  0s, 127.33MB/s
indexed 34.86MB in  0s, 127.43MB/s
indexed 35.00MB in  0s, 127.47MB/s
indexed 35.13MB in  0s, 127.46MB/s
indexed 35.26MB in  0s, 127.43MB/s
indexed 35.39MB in  0s, 127.45MB/s
indexed 35.52MB in  0s, 127.50MB/s
indexed 35.65MB in  0s, 127.51MB/s
indexed 35.78MB in  0s, 127.60MB/s
indexed 35.91MB in  0s, 127.64MB/s
indexed 36.04MB in  0s, 127.65MB/s
indexed 36.18MB in  0s, 127.82MB/s
indexed 36.31MB in  0s, 127.85MB/s
indexed 36.44MB in  0s, 127.88MB/s
indexed 36.57MB in  0s, 128.04MB/s
indexed 36.70MB in  0s, 128.22MB/s
indexed 36.83MB in  0s, 128.39MB/s
indexed 36.96MB in  0s, 128.36MB/s
indexed 37.09MB in  0s, 128.43MB/s
indexed 37.22MB in  0s, 128.56MB/s
indexed 37.36MB in  0s, 128.57MB/s
indexed 37.49MB in  0s, 128.72MB/s
indexed 37.62MB in  0s, 128.72MB/s
indexed 37.75MB in  0s, 128.87MB/s
indexed 37.88MB in  0s, 128.91MB/s
indexed 38.01MB in  0s, 128.99MB/s
indexed 38.14MB in  0s, 129.08MB/s
indexed 38.27MB in  0s, 129.20MB/s
indexed 38.40MB in  0s, 129.25MB/s
indexed 38.53MB in  0s, 129.38MB/s
indexed 38.67MB in  0s, 129.47MB/s
indexed 38.80MB in  0s, 129.45MB/s
indexed 38.93MB in  0s, 129.43MB/s
indexed 39.06MB in  0s, 129.51MB/s
indexed 39.19MB in  0s, 129.63MB/s
indexed 39.32MB in  0s, 129.73MB/s
indexed 39.45MB in  0s, 129.79MB/s
indexed 39.58MB in  0s, 129.90MB/s
indexed 39.71MB in  0s, 129.95MB/s
indexed 39.85MB in  0s, 130.11MB/s
indexed 39.98MB in  0s, 130.14MB/s
indexed 40.11MB in  0s, 130.16MB/s
indexed 40.24MB in  0s, 130.21MB/s
indexed 40.37MB in  0s, 130.35MB/s
indexed 40.50MB in  0s, 130.43MB/s
indexed 40.63MB in  0s, 130.49MB/s
indexed 40.76MB in  0s, 130.51MB/s
indexed 40.89MB in  0s, 130.63MB/s
indexed 41.03MB in  0s, 130.75MB/s
indexed 41.16MB in  0s, 130.86MB/s
indexed 41.29MB in  0s, 130.80MB/s
indexed 41.42MB in  0s, 130.85MB/s
indexed 41.55MB in  0s, 130.68MB/s
indexed 41.68MB in  0s, 130.74MB/s
indexed 41.81MB in  0s, 130.70MB/s
indexed 41.94MB in  0s, 130.65MB/s
indexed 42.07MB in  0s, 130.70MB/s
indexed 42.20MB in  0s, 130.77MB/s
indexed 42.34MB in  0s, 130.91MB/s
indexed 42.47MB in  0s, 130.98MB/s
indexed 42.60MB in  0s, 131.04MB/s
indexed 42.73MB in  0s, 131.10MB/s
indexed 42.86MB in  0s, 131.19MB/s
indexed 42.99MB in  0s, 131.31MB/s
indexed 43.12MB in  0s, 131.39MB/s
indexed 43.25MB in  0s, 131.51MB/s
indexed 43.38MB in  0s, 131.56MB/s
indexed 43.52MB in  0s, 131.69MB/s
indexed 43.65MB in  0s, 131.63MB/s
indexed 43.78MB in  0s, 131.71MB/s
indexed 43.91MB in  0s, 131.80MB/s
indexed 44.04MB in  0s, 131.91MB/s
indexed 44.17MB in  0s, 132.03MB/s
indexed 44.30MB in  0s, 132.02MB/s
indexed 44.43MB in  0s, 132.13MB/s
indexed 44.56MB in  0s, 132.18MB/s
indexed 44.70MB in  0s, 132.17MB/s
indexed 44.83MB in  0s, 132.18MB/s
indexed 44.96MB in  0s, 132.23MB/s
indexed 45.09MB in  0s, 132.23MB/s
indexed 45.22MB in  0s, 132.23MB/s
indexed 45.35MB in  0s, 132.33MB/s
indexed 45.48MB in  0s, 132.43MB/s
indexed 45.61MB in  0s, 132.50MB/s
indexed 45.74MB in  0s, 132.54MB/s
indexed 45.87MB in  0s, 132.63MB/s
indexed 46.01MB in  0s, 132.65MB/s
indexed 46.14MB in  0s, 132.55MB/s
indexed 46.27MB in  0s, 132.58MB/s
indexed 46.40MB in  0s, 132.62MB/s
indexed 46.53MB in  0s, 132.47MB/s
indexed 46.66MB in  0s, 132.52MB/s
indexed 46.79MB in  0s, 132.58MB/s
indexed 46.92MB in  0s, 132.70MB/s
indexed 47.05MB in  0s, 132.79MB/s
indexed 47.19MB in  0s, 132.87MB/s
indexed 47.32MB in  0s, 132.95MB/s
indexed 47.45MB in  0s, 133.00MB/s
indexed 47.58MB in  0s, 133.00MB/s
indexed 47.71MB in  0s, 133.11MB/s
indexed 47.84MB in  0s, 133.22MB/s
indexed 47.97MB in  0s, 133.22MB/s
indexed 48.10MB in  0s, 133.23MB/s
indexed 48.23MB in  0s, 133.29MB/s
indexed 48.37MB in  0s, 133.39MB/s
indexed 48.50MB in  0s, 133.39MB/s
indexed 48.63MB in  0s, 133.43MB/s
indexed 48.76MB in  0s, 133.45MB/s
indexed 48.89MB in  0s, 133.51MB/s
indexed 49.02MB in  0s, 133.54MB/s
indexed 49.15MB in  0s, 133.57MB/s
indexed 49.28MB in  0s, 133.63MB/s
indexed 49.41MB in  0s, 133.73MB/s
indexed 49.54MB in  0s, 133.73MB/s
indexed 49.68MB in  0s, 133.76MB/s
indexed 49.81MB in  0s, 133.81MB/s
indexed 49.94MB in  0s, 133.85MB/s
indexed 50.07MB in  0s, 133.94MB/s
indexed 50.20MB in  0s, 133.97MB/s
indexed 50.33MB in  0s, 134.01MB/s
indexed 50.46MB in  0s, 134.00MB/s
indexed 50.59MB in  0s, 129.22MB/s
indexed 50.72MB in  0s, 129.24MB/s
indexed 50.86MB in  0s, 129.31MB/s
indexed 50.99MB in  0s, 129.32MB/s
indexed 51.12MB in  0s, 129.40MB/s
indexed 51.25MB in  0s, 129.51MB/s
indexed 51.38MB in  0s, 129.61MB/s
indexed 51.51MB in  0s, 129.66MB/s
indexed 51.64MB in  0s, 129.78MB/s
indexed 51.77MB in  0s, 129.79MB/s
indexed 51.90MB in  0s, 129.88MB/s
indexed 52.04MB in  0s, 129.72MB/s
indexed 52.17MB in  0s, 129.77MB/s
indexed 52.30MB in  0s, 129.83MB/s
indexed 52.43MB in  0s, 129.89MB/s
indexed 52.56MB in  0s, 129.95MB/s
indexed 52.69MB in  0s, 130.03MB/s
indexed 52.82MB in  0s, 130.06MB/s
indexed 52.95MB in  0s, 130.07MB/s
indexed 53.08MB in  0s, 130.11MB/s
indexed 53.21MB in  0s, 130.20MB/s
indexed 53.35MB in  0s, 130.19MB/s
indexed 53.48MB in  0s, 130.26MB/s
indexed 53.61MB in  0s, 130.35MB/s
indexed 53.74MB in  0s, 130.43MB/s
indexed 53.87MB in  0s, 130.54MB/s
indexed 54.00MB in  0s, 130.65MB/s
indexed 54.13MB in  0s, 130.63MB/s
indexed 54.26MB in  0s, 130.66MB/s
indexed 54.39MB in  0s, 130.73MB/s
indexed 54.53MB in  0s, 130.79MB/s
indexed 54.66MB in  0s, 130.76MB/s
indexed 54.79MB in  0s, 130.88MB/s
indexed 54.92MB in  0s, 130.90MB/s
indexed 55.05MB in  0s, 130.96MB/s
indexed 55.18MB in  0s, 131.07MB/s
indexed 55.31MB in  0s, 131.17MB/s
indexed 55.44MB in  0s, 131.26MB/s
indexed 55.57MB in  0s, 131.36MB/s
indexed 55.71MB in  0s, 131.45MB/s
indexed 55.84MB in  0s, 131.58MB/s
indexed 55.97MB in  0s, 131.68MB/s
indexed 56.10MB in  0s, 131.69MB/s
indexed 56.23MB in  0s, 131.80MB/s
indexed 56.36MB in  0s, 131.86MB/s
indexed 56.49MB in  0s, 131.95MB/s
indexed 56.62MB in  0s, 132.05MB/s
indexed 56.75MB in  0s, 132.16MB/s
indexed 56.88MB in  0s, 132.19MB/s
indexed 57.02MB in  0s, 132.30MB/s
indexed 57.15MB in  0s, 132.33MB/s
indexed 57.28MB in  0s, 132.41MB/s
indexed 57.41MB in  0s, 132.52MB/s
indexed 57.54MB in  0s, 132.60MB/s
indexed 57.67MB in  0s, 132.70MB/s
indexed 57.80MB in  0s, 132.77MB/s
indexed 57.93MB in  0s, 132.87MB/s
indexed 58.06MB in  0s, 132.95MB/s
indexed 58.20MB in  0s, 133.00MB/s
indexed 58.33MB in  0s, 133.07MB/s
indexed 58.46MB in  0s, 133.14MB/s
indexed 58.59MB in  0s, 133.24MB/s
indexed 58.72MB in  0s, 133.31MB/s
indexed 58.85MB in  0s, 133.27MB/s
indexed 58.98MB in  0s, 133.29MB/s
indexed 59.11MB in  0s, 133.31MB/s
indexed 59.24MB in  0s, 133.38MB/s
indexed 59.38MB in  0s, 133.40MB/s
indexed 59.51MB in  0s, 133.45MB/s
indexed 59.64MB in  0s, 133.56MB/s
indexed 59.77MB in  0s, 133.57MB/s
indexed 59.90MB in  0s, 133.63MB/s
indexed 60.03MB in  0s, 133.71MB/s
indexed 60.16MB in  0s, 133.77MB/s
indexed 60.29MB in  0s, 133.68MB/s
indexed 60.42MB in  0s, 133.69MB/s
indexed 60.55MB in  0s, 133.77MB/s
indexed 60.69MB in  0s, 133.82MB/s
indexed 60.82MB in  0s, 133.93MB/s
indexed 60.95MB in  0s, 134.01MB/s
indexed 61.08MB in  0s, 134.08MB/s
indexed 61.21MB in  0s, 134.15MB/s
indexed 61.34MB in  0s, 134.10MB/s
indexed 61.47MB in  0s, 134.13MB/s
indexed 61.60MB in  0s, 134.22MB/s
indexed 61.73MB in  0s, 134.25MB/s
indexed 61.87MB in  0s, 134.28MB/s
indexed 62.00MB in  0s, 134.38MB/s
indexed 62.13MB in  0s, 134.49MB/s
indexed 62.26MB in  0s, 134.58MB/s
indexed 62.39MB in  0s, 134.67MB/s
indexed 62.52MB in  0s, 134.74MB/s
indexed 62.65MB in  0s, 134.77MB/s
indexed 62.78MB in  0s, 134.77MB/s
indexed 62.91MB in  0s, 134.88MB/s
indexed 63.05MB in  0s, 134.89MB/s
indexed 63.18MB in  0s, 134.91MB/s
indexed 63.31MB in  0s, 135.02MB/s
indexed 63.44MB in  0s, 135.12MB/s
indexed 63.57MB in  0s, 135.17MB/s
indexed 63.70MB in  0s, 135.19MB/s
indexed 63.83MB in  0s, 135.26MB/s
indexed 63.96MB in  0s, 135.34MB/s
indexed 64.09MB in  0s, 135.37MB/s
indexed 64.22MB in  0s, 135.48MB/s
indexed 64.36MB in  0s, 135.53MB/s
indexed 64.49MB in  0s, 135.62MB/s
indexed 64.62MB in  0s, 135.69MB/s
indexed 64.75MB in  0s, 135.73MB/s
indexed 64.88MB in  0s, 135.81MB/s
indexed 65.01MB in  0s, 135.90MB/s
indexed 65.14MB in  0s, 135.98MB/s
indexed 65.27MB in  0s, 136.01MB/s
indexed 65.40MB in  0s, 136.10MB/s
indexed 65.54MB in  0s, 136.19MB/s
indexed 65.56MB in  0s, 135.98MB/s
                                                                              
indexed 2.15GB in  0s, 2.15GB/s
                                                                              

# 2. Filtrar, Manipular y Calcular el Promedio Anual
datos_comparacion_anual <- df %>% 
  filter(
    freq == "M",       
    unit == "I05",     
    coicop == "CP041", 
    geo %in% c("ES", "FR", "DE", "EA19"), 
    TIME_PERIOD >= "2015-01"
  ) %>%
  mutate(
    Año = substr(TIME_PERIOD, 1, 4),
    Fecha_Anual = ymd(paste0(Año, "-01-01"))
  ) %>%
  group_by(Año, Fecha_Anual, geo) %>%
  summarise(
    values = mean(values, na.rm = TRUE),
    .groups = 'drop'
  ) %>%
  drop_na(Fecha_Anual, values) %>%
  mutate(
    Pais = case_when(
      geo == "ES" ~ "España",
      geo == "FR" ~ "Francia",
      geo == "DE" ~ "Alemania",       
      geo == "EA19" ~ "Eurozona (EA19)",
      TRUE ~ geo
    ))

# Definición de la paleta de colores deseada
colores_personalizados <- c(
  "España" = "#36648B",              
  "Eurozona (EA19)" = "#8B2323",     
  "Alemania" = "gray50",          
  "Francia" = "#A2B5CD"            
)

# Generar el gráfico con los 4 territorios y colores manuales
grafico_hicp_colores <- datos_comparacion_anual %>%
  ggplot(aes(x = Fecha_Anual, y = values, color = Pais)) +
  geom_line(linewidth = 1) +
  geom_point(size = 2) +
  scale_color_manual(values = colores_personalizados) +
  labs(
    title = "Índice de precios del alquiler",
    x = "Año",
    y = "Índice (2015 = 100)",
    color = "Territorio", 
    caption = "Fuente: Eurostat (prc_hicp_midx) | Cálculo: Promedio de valores mensuales."
  ) +
  scale_x_date(date_breaks = "1 year", date_labels = "%Y") +
  theme_minimal() +
  theme(
    plot.title = element_text(family = "sans",
          size = 12,
          face = "plain"),
    plot.subtitle = element_text(size = 8, color = "gray50"),
    axis.text.x = element_text(angle = 0, hjust = 1, size = 8),
    axis.text.y = element_text(size = 8),
    legend.position = "bottom")

# Mostrar el gráfico
print(grafico_hicp_colores)

3.3. Índice de precios de la vivienda nueva y antigua

  • Los precios suben en todos los países entre 2015 y 2024.

  • Alemania registra los niveles más altos en 2024.

  • España destaca por la fuerte caída entre 2006 y 2015 debido a la burbuja inmobiliaria.

  • Tanto vivienda nueva como existente siguen patrones similares.

  • En España el ajuste afectó a todo el mercado, a diferencia de Francia y Alemania, más estables.

Código
#- tercer gráfico
my_table <- "prc_hpi_a"        #- seleccioné la tabla: "Indice de precios de la vivienda 

label_eurostat_tables(my_table)     # informacion de la tabla
#> [1] "House price index (2015 = 100) - annual data"


#- descarga la base de datos de Eurostat API
df <- get_eurostat(my_table, time_format = 'raw', keepFlags = TRUE)
#> 
indexed 0B in  0s, 0B/s
indexed 2.15GB in  0s, 2.15GB/s
                                                                              


# --- DATOS INICIALES Y CARGA (No se repiten los pasos de preparación de datos) ---
paises_deseados <- c("ES", "FR", "DE")
años_barras <- c(2006, 2015, 2024)
colores_barras <- c("2006" = "#A2B5CD", "2015" = "#8B7D6B", "2024" = "#36648b") 


# Base de datos filtrada para EXST
df_europa_filtrado_EXST <- df %>%
  filter(freq == "A") %>%
  filter(purchase == "DW_EXST") %>%
  filter(geo %in% paises_deseados) %>%
  filter(
    unit == "I10_A_AVG",
    !is.na(values)
  )

df_barras_EXST <- df_europa_filtrado_EXST %>%
  mutate(TIME_PERIOD = as.character(TIME_PERIOD)) %>%
  filter(TIME_PERIOD %in% años_barras) %>%
  mutate(TIME_PERIOD = factor(TIME_PERIOD, levels = años_barras))


# Base de datos para NEW
df_europa_filtrado_NEW <- df %>%
  filter(freq == "A") %>%
  filter(purchase == "DW_NEW") %>%
  filter(geo %in% paises_deseados) %>%
  filter(
    unit == "I10_A_AVG",
    !is.na(values)
  )

df_barras <- df_europa_filtrado_NEW %>%
  mutate(TIME_PERIOD = as.character(TIME_PERIOD)) %>%
  filter(TIME_PERIOD %in% años_barras) %>%
  mutate(TIME_PERIOD = factor(TIME_PERIOD, levels = años_barras))


# Graficos juntos
grafico_barras_NEW <- ggplot(data = df_barras,
                             aes(x = geo, y = values, fill = TIME_PERIOD)) +
  geom_col(position = "dodge") +
  labs(
    title = "A. Viviendas de Nueva Construcción",
    x = "",
    y = "Índice de Precios",
    fill = "Año" 
  ) +
  scale_fill_manual(values = colores_barras) +
  scale_y_continuous(limits = c(0, 200), breaks = seq(0, 200, 50)) + 
  theme_minimal() +
  theme(plot.title = element_text(face = "plain", size = 12), 
        axis.title.x = element_text(size = 7), 
        axis.title.y = element_text(size=7))


grafico_barras_EXST <- ggplot(data = df_barras_EXST, 
                              aes(x = geo, y = values, fill = TIME_PERIOD)) +
  geom_col(position = "dodge") +
  labs(
    title = "B. Viviendas Existentes",
    x = "",
    y = "",
    fill = "Año"
  ) +
  scale_fill_manual(values = colores_barras) +
  scale_y_continuous(limits = c(0, 200), breaks = seq(0, 200, 50)) + 
  theme_minimal() +
  theme(plot.title = element_text(face = "plain", size = 12), 
        axis.title.x = element_text(size = 7), 
        axis.title.y = element_text(size=7))

grafico_combinado <- (grafico_barras_NEW + grafico_barras_EXST)

grafico_final <- grafico_combinado +
  plot_layout(
    guides = 'collect', 
    widths = c(1, 1)    
  ) & 
  theme(legend.position = "bottom")

grafico_final <- grafico_final +
  plot_annotation(
    title = 'Comparación del Índice de Precios de la Vivienda',
    theme(plot.title = element_text(face = "plain", size = 12), 
        axis.title.x = element_text(size = 8), 
        axis.title.y = element_text(size=8))  )

# Grafico final
print(grafico_final)

4. Relación entre la vivienda y la renta de los hogares

4.1. Comparación de los salarios con los ingresos

  • La ratio renta-precio mide si los precios crecen más rápido que los ingresos.

  • En España se observan ciclos claros: auge pre-2008, ajuste fuerte y nueva presión desde 2015.

  • El aumento reciente indica deterioro de la asequibilidad.

  • Francia y Alemania muestran trayectorias más estables que España.

Código
ruta <- "./datos/standarised_house_income.csv" 
df_ocde <- rio::import(ruta) 

codigos_paises_2 <- c("ESP", # España
                       "FRA", # Francia
                       "DEU") # Alemania 
                       
 df_ocde_2 <- df_ocde |> select(TIME_PERIOD, OBS_VALUE, REF_AREA) |> filter(REF_AREA %in% codigos_paises_2) |> filter(TIME_PERIOD %in% c(2005:2024))

colores <- c( "ESP" = "#36648B", 
              "FRA" = "#A2B5CD",  
              "DEU" = "#A9A9A9") 
              
ggplot(data = df_ocde_2, aes(x = TIME_PERIOD, y = OBS_VALUE)) + 
  geom_line(aes(group = REF_AREA), color = "#A2B5CD", linewidth = 0.7, alpha = 0.3) + 
  geom_line(data = df_ocde_2 %>% filter(REF_AREA %in% codigos_paises_2),
            aes(color = REF_AREA, group = REF_AREA),
            linewidth = 1) +  
  scale_color_manual(values = colores) +
  labs(title = "Ratio de ingresos de los hogares ajustado por tamaño",
       x = "Año",
       y = "Índice de Precios",
       caption = "Fuente: OCDE") +
    annotate("text", x = 2025, y = 112, label = "España", color = "#36648B", size = 3) +
  annotate("text", x = 2025, y = 108, label = "Francia", color = "#A2B5CD", size = 3) +
  annotate("text", x = 2025, y = 88, label = "Alemania", color = "#A9A9A9", size = 3) +
  annotate("rect",
           xmin = 2008, xmax = 2012,
           ymin = -Inf, ymax = Inf,
           alpha = 0.2, fill = "red") +
  annotate("text",
           x = 2010, y = max(df_ocde_2$OBS_VALUE) * 0.95, 
           label = "Crisis Hipotecaria", color = "red", size = 4) +
  annotate("rect",
           xmin = 2020, xmax = 2022,
           ymin = -Inf, ymax = Inf,
           alpha = 0.2, fill = "red") +
  annotate("text",
           x = 2021, y = max(df_ocde_2$OBS_VALUE) * 0.95, 
           label = "Crisis COVID", color = "red", size = 4) +
  theme_minimal() +
  theme(legend.position = "none", 
        panel.grid.major.x = element_blank(), 
        panel.grid.minor.x = element_blank(), 
        axis.text.x = element_text(angle = 0, hjust = 1),
        plot.title = element_text(family = "sans", size = 12, face = "plain"), 
        axis.title.x = element_text(size = 8),
        axis.title.y = element_text(size=8))

4.2. Umbral riesgo de pobreza

  • El umbral mide el ingreso mínimo para evitar pobreza, ajustado por poder adquisitivo.

  • España se sitúa en la parte baja-media de la UE.

  • Refleja menores ingresos medianos respecto a Europa central y del norte.

  • Las diferencias estructurales de renta explican gran parte del problema habitacional.

Código
# UMBRAL DE POBREZA

my_table <- "ilc_li01"       

label_eurostat_tables(my_table)    
#> [1] "At-risk-of-poverty thresholds"

#- descarga la base de datos de Eurostat API
df2 <- get_eurostat(my_table, time_format = 'raw', keepFlags = TRUE)
#> 
indexed 0B in  0s, 0B/s
indexed 2.15GB in  0s, 2.15GB/s
                                                                              


# Verificar variables
df2 %>% 
  distinct(hhtyp)
#> # A tibble: 3 × 1
#>   hhtyp      
#>   <chr>      
#> 1 A1         
#> 2 A2         
#> 3 A2_2CH_LT14

df2 %>% 
  distinct(indic_il)
#> # A tibble: 7 × 1
#>   indic_il 
#>   <chr>    
#> 1 LI_C_M40 
#> 2 LI_C_M50 
#> 3 LI_C_M60 
#> 4 LI_C_MD40
#> 5 LI_C_MD50
#> 6 LI_C_MD60
#> 7 LI_C_MD70

df2 %>% 
  distinct(currency)
#> # A tibble: 3 × 1
#>   currency
#>   <chr>   
#> 1 EUR     
#> 2 NAC     
#> 3 PPS

codigos_ue <- c(
  "AT", "BE", "BG", "HR", "CZ", "CY", "DK", "SK", "SI", "ES", 
  "EE", "FI", "FR", "EL", "HU", "IE", "IT", "LV", "LT", "LU", 
  "MT", "NL", "PL", "PT", "RO", "SE", "DE"
)

df_filtrado_A1 <- df2 %>%
  filter(
    hhtyp == "A1" ,
    currency == "PPS",
    indic_il == "LI_C_M60",
    geo %in% codigos_ue ,
    TIME_PERIOD == "2024"
  )


# --- PASO 1: Descargar Geometrías ---
europa_sf <- gisco_get_countries(
  year = "2020",
  resolution = "20",
  country = codigos_ue, 
  epsg = "4326"
)

europa_sf <- europa_sf %>%
  rename(geo = CNTR_ID) 

# --- PASO 2: Unir datos de Eurostat con las geometrías ---
df_mapa <- left_join(europa_sf, df_filtrado_A1, by = "geo")


nombre_columna_valor <- "values" 

nombre_columna_pais <- "NAME_LATN" 


mypalette <- colorNumeric( 
  palette = "cividis", 
  domain = df_mapa[[nombre_columna_valor]], 
  na.color = "transparent"
)

mytext <- paste(
  "País: ", df_mapa[[nombre_columna_pais]], "<br/>", 
  "Indicador (LI_C_M60): ",  df_mapa$indic_il, "<br/>", 
  "Valor (PPS, 2024): ", round(df_mapa[[nombre_columna_valor]], 0), 
  sep = ""
) %>%
  lapply(htmltools::HTML)

# 3. Crear y mostrar el mapa
mapa <- leaflet(df_mapa) %>% 
  addTiles()  %>% 
  setView(lat = 50, lng = 10, zoom = 3) %>% 
  addPolygons( 
    fillColor = ~mypalette(df_mapa[[nombre_columna_valor]]), 
    stroke = TRUE, 
    fillOpacity = 0.9, 
    color = "white", 
    weight = 0.5,
    label = mytext,
    labelOptions = labelOptions( 
      style = list("font-weight" = "normal", padding = "3px 8px"), 
      textsize = "13px", 
      direction = "auto"
    )
  ) %>%
  addLegend( 
    pal = mypalette, 
    values = ~df_mapa[[nombre_columna_valor]], 
    opacity = 0.9, 
    title = "Umbral riesgo de pobreza (PPS)", 
    position = "bottomleft" 
  )%>%
  htmlwidgets::onRender("
    function(el, x) {
      el.style.width = '80%';
      el.style.height = '600px';
    }
  ")


mapa

4.3. Consumo anual de los hogares

  • El gasto en vivienda y suministros crece en todos los países.

  • Alemania y Francia concentran los mayores volúmenes absolutos.

  • España muestra un fuerte aumento pre-crisis y una posterior estabilización.

  • El consumo sigue creciendo incluso en 2020, pese a la pandemia.

  • El sur de Europa es más sensible a los ciclos económicos.

Código
#Gasto final de consumo anual de los hogares: Vivienda, agua, electricidad, gas y otros combustibles

df_01 <- rio::import("./datos/Annual_household_final_consumption.csv")

codigos_paises_01 <- c(
  "ESP", # España
  "FRA", # Francia
  "DEU", # Alemania
  "ITA", # Italia
  "BEL", #Belgica
  "PRT", #Portugal
  "IRL" # Irlanda
)

df_02 <- df_01 %>%
  filter(TIME_PERIOD %in% c(2005,2010,2015,2020)) %>% 
  select("REF_AREA", "OBS_VALUE", "TIME_PERIOD", "CURRENCY", "FREQ") %>% 
  filter(FREQ == "A") %>%
  filter(REF_AREA %in% codigos_paises_01)

df_02 <- df_02 %>% 
  select(REF_AREA, TIME_PERIOD, OBS_VALUE) %>% 
  mutate(REF_AREA.f = forcats::as_factor(REF_AREA), .after = REF_AREA) %>% 
  mutate(REF_AREA.f = forcats::fct_recode(REF_AREA.f,
                                     "España" = "ESP",
                                     "Francia" = "FRA", 
                                     "Alemania" = "DEU",
                                     "Italia" = "ITA",
                                     "Bélgica" = "BEL",
                                     "Portugal" = "PRT",
                                     "Irlanda" = "IRL")) 
df_02 <- df_02 %>% 
  select(REF_AREA.f, TIME_PERIOD, OBS_VALUE) %>% 
  rename(year = TIME_PERIOD) %>% 
  rename (countries = REF_AREA.f)


df_02 <- df_02 %>% 
  pivot_wider(names_from = year, values_from = OBS_VALUE) 

tt_1 <- gt::gt(df_02)

tt_1 %>%
  gtExtras::gt_theme_pff() %>% 
  tab_header(title = md("**Gasto final del consumo anual de los hogares**"),
             subtitle = "Vivienda, agua, electricidad, gas y otros combustibles") %>% 
  opt_align_table_header(align = "left")  %>% 
  tab_style(
    style = cell_text(size = px(23)),   
    locations = cells_body()
  ) %>%
  tab_style(style = cell_text(size = px(26)),
            locations = cells_title("title")) %>% 
  tab_source_note(md("Fuente: datos de la [OCDE](https://www.oecd.org/en.html)")) %>% 
  tab_footnote(footnote = "En Millones de Euros", 
               placement = "right",
               location = cells_title("title")) %>% 
  cols_align(align = "center")
Gasto final del consumo anual de los hogares1
Vivienda, agua, electricidad, gas y otros combustibles
countries 2005 2010 2015 2020
Alemania 305371.00 340652.00 375048.00 420033.00
España 96249.00 142858.00 150754.00 159444.00
Portugal 14704.50 19743.93 22941.03 26299.91
Bélgica 32922.40 41498.60 49017.80 55496.50
Italia 179760.50 216341.40 235796.30 242005.60
Irlanda 14245.82 16612.67 20315.35 26156.49
Francia 225042.00 274755.00 306758.00 336356.00
1 En Millones de Euros
Fuente: datos de la OCDE

4.4. Asequibilidad de la vivienda

  • El indicador mide el ingreso disponible tras pagar costes de vivienda.

  • Se observa un deterioro hasta 2012 por la crisis financiera.

  • Alemania mantiene mayor estabilidad y mejor asequibilidad.

  • España sufre un fuerte deterioro y posterior estabilización.

  • Francia muestra un empeoramiento moderado gracias a políticas sociales.

  • Existen claras desigualdades regionales en Europa.

Código
#Asequibilidad de la vivienda
df_05 <- rio::import("./datos/Housing_affordability.csv")

codigos_paises_03 <- c(
  "ESP", # España
  "FRA", # Francia
  "DEU" #Alemania 
  )

df_06 <- df_05 %>%
  select("REF_AREA", "OBS_VALUE", "TIME_PERIOD") %>% 
  filter(REF_AREA %in% codigos_paises_03)

ggplot(data = df_06, aes(x = TIME_PERIOD, y = OBS_VALUE)) +
  geom_line(data= df_06 %>% filter(REF_AREA == "DEU"), aes(color = REF_AREA, group = REF_AREA), color = "#8B7D6B", linewidth = 1)+
  geom_line(data= df_06 %>% filter(REF_AREA == "ESP"), aes(color = REF_AREA, group = REF_AREA), color = "#36648B", linewidth = 1) +
  geom_line(data= df_06 %>% filter(REF_AREA == "FRA"), aes(color = REF_AREA, group = REF_AREA), color = "#A2B5CD", linewidth = 1) +
  scale_y_continuous(labels = function(x) paste0(x, "%")) +
  labs(
    title = "Asequibilidad de la vivienda",
    subtitle = "Porcentaje del ingreso bruto disponible del hogar que queda, después de las \ndeducciones por alquileres y mantenimiento de la vivienda",
    x = "Año",
    y = "Tasa de ingreso bruto dispobible",
    caption = "Fuente: OECD") +
  annotate("text", x = 2020, y = 78.4, label = "Francia", color = "#A2B5CD", size = 3) + 
  annotate("text", x = 2020, y = 78.7, label = "España", color = "#36648B", size = 3) + 
  annotate("text", x = 2020, y = 80.8, label = "Alemania", color = "#8B7D6B", size = 3) + 
  theme_minimal() +
  theme(
    panel.grid.major.x = element_blank(), 
    panel.grid.minor.x = element_blank(), 
    axis.text.x = element_text(angle = 0, hjust = 1, size = 8),
    axis.text.y = element_text(size = 8), 
    plot.title = element_text(
      family = "sans",
      size = 12,
      face = "plain"), 
      plot.subtitle = element_text(
      family = "sans",
      size = 10,
      face = "plain"))

4.5. Distribución de la población según la carga del coste de la vivienda y el grado de urbanización

  • Se analiza la sobrecarga (>40% de la renta) en grandes ciudades.

  • La tasa disminuye en la UE, España y Francia desde 2010.

  • España presenta mayor volatilidad y sensibilidad a crisis.

  • Francia mantiene niveles bajos y estables gracias a intervención pública.

  • Persisten riesgos para hogares de bajos ingresos en zonas urbanas.

Código
my_table <- "ilc_lvho29"      

label_eurostat_tables(my_table) 
#> [1] "Distribution of population by housing cost burden and degree of urbanisation"

df <- get_eurostat(my_table, time_format = 'raw', keepFlags = TRUE)
#> 
indexed 0B in  0s, 0B/s
indexed 2.15GB in  0s, 2.15GB/s
                                                                              

df %>% 
  distinct(unit)
#> # A tibble: 1 × 1
#>   unit 
#>   <chr>
#> 1 PC

df %>% 
  distinct(freq) 
#> # A tibble: 1 × 1
#>   freq 
#>   <chr>
#> 1 A

codigos_paises <- c(
  "EU27_2020",
  "ES", # España
  "FR", # Francia
  "DE", # Alemania
  "IT", # Italia
  "BE", #Belgica
  "PT", #Portugal
  "IE" # Irlanda
)

codigos_paises_00 <- c(
  "EU27_2020",
  "ES", # España
  "FR" # Francia
)

df_0 <- df %>%
  filter (TIME_PERIOD >= 2010) %>% 
  filter(freq == "A") %>%
  filter(deg_urb == "DEG1") %>% 
  filter(indic_il == "A40DI") %>% 
  filter(geo %in% codigos_paises_00) %>%
  filter(
    unit == "PC", 
    !is.na(values)    
  )  %>%
  mutate(TIME_PERIOD = as.integer(TIME_PERIOD))


ggplot(data = df_0, aes(x = TIME_PERIOD, y = values)) +
  geom_line(aes(group = geo), color = "#A2B5CD", linewidth = 0.7, alpha = 0.6) +
  geom_line(data = df_0 %>% filter(geo == "ES"), aes(group = geo), color = "#36648B", linewidth = 1) +
  geom_line(data = df_0 %>% filter(geo == "EU27_2020"), aes(group = geo), color = "#8B2323", linewidth = 1) +
   scale_y_continuous(labels = function(x) paste0(x, "%")) +
  labs(
    title = "Distribución de la población según la carga del coste de la vivienda",
    subtitle = "Carga de los costes de vivienda superior al 40 % de la renta disponible del hogar \nen zonas urbanas grandes ",
    x = "Año",
    y = "Tasa de sobrecarga del coste de la vivienda",
    caption = "Fuente: Eurostat"
  ) +
  annotate("text", x = 2025, y = 8.5, label = "España", color = "#36648B", size = 3) +
  annotate("text", x = 2025, y = 9.3, label = "Francia", color = "#A2B5CD", size = 3) +
  annotate("text", x = 2025, y = 9.7, label = "UE", color = "#8B2323", size = 3) +
  scale_y_continuous(labels = function(x) paste0(x, "%")) +
  theme_minimal() +
  theme(
    legend.position = "right", 
    panel.grid.major.x = element_blank(), 
    panel.grid.minor.x = element_blank(), 
    axis.text.x = element_text(angle = 0, hjust = 1, size = 8),
    axis.text.y = element_text(size = 8), 
    plot.title = element_text(family = "sans", size = 12, face = "plain"), 
    plot.subtitle = element_text(family = "sans", size = 10, face = "plain")
  ) 

4.6. Hogares que viven en condiciones de hacinamiento

  • La tasa de hacinamiento disminuye en la mayoría de países.

  • Indica mejoras en acceso y calidad de la vivienda post-crisis.

  • Italia y Bélgica muestran empeoramientos leves.

  • España mantiene niveles bajos y mejora moderadamente.

  • Persisten desigualdades regionales dentro de la UE.

Código
#Hogares que viven en condiciones de hacinamiento

df_03 <- rio::import("./datos/Households_living_in_overcrowded_conditions.csv")

codigos_paises_02 <- c(
  "ESP", # España
  "FRA", # Francia
  "ITA", # Italia
  "BEL", #Belgica
  "PRT", #Portugal
  "IRL" # Irlanda
)

df_04 <- df_03 %>%
  select(REF_AREA, OBS_VALUE, TIME_PERIOD) %>% 
  filter(REF_AREA %in% codigos_paises_02) %>% 
  filter(TIME_PERIOD %in% c(2010,2018))

df_04 %>%
  mutate(REF_AREA = fct_reorder(REF_AREA, OBS_VALUE, .fun = max)) %>%
  ggplot(aes(REF_AREA, OBS_VALUE, fill = factor(TIME_PERIOD))) +
  geom_col(position = position_dodge(0.8)) +
  scale_fill_manual(
    values = c(
      "2010" = "#A6B8CF",
      "2018" = "#355C7D" )) +
  scale_y_continuous(labels = function(x) paste0(x, "%")) +
  labs(
    title = "Porcentaje de hogares que viven en condiciones de hacinamiento",
    subtitle = "Comparación entre los años 2010 y 2018",
    x = "País",
    y = "Tasa de hacinamiento",
    fill = "Año"
  ) +
  theme_minimal() + 
  theme(plot.title = element_text(
          family = "sans",
          size = 12,
          face = "plain"), 
        axis.text.x = element_text(size = 8),
        axis.text.y = element_text(size = 8))

5. Acceso a la vivienda en términos financieros

  • El tipo de interés es un factor clave del ciclo inmobiliario.

  • Tipos bajos (2009–2021) impulsan el crédito y los precios de la vivienda.

  • Desde 2022, la subida de tipos encarece las hipotecas y reduce la demanda.

  • El endurecimiento monetario frena el mercado inmobiliario.

  • El acceso a la vivienda depende fuertemente de la política monetaria del BCE.

Código
tabla_tipo_interes <- rio::import("./datos/datos_ECB_tipo_interes.csv")

tabla_tipo_interes_2 <- tabla_tipo_interes |> 
  separate(`TIME PERIOD`, into = c("Year", "Month"), sep = 4) |> 
  group_by(Year) |> 
  summarise(media_anual_interes = mean(`Cost of borrowing for households for house purchase  (MIR.M.U2.B.A2C.AM.R.A.2250.EUR.N)`))


ggplot(tabla_tipo_interes_2, aes(x = Year, y = media_anual_interes)) + 
  geom_line(aes(group = 1), color = "#36648B", linewidth = 0.8) + 
  labs(title = "Tipo de interés hipotecario promedio aplicado por bancos de la zona euro a nuevas hipotecas /n para compra de vivienda", 
       subtitle = "AAR Interes", 
       x = "Año", 
       y = "Tipo de interés", 
       caption = "Fuente: Banco Central Europeo") + 
  scale_x_discrete(breaks = seq(2003, 2025, by = 4))