Loyers et taux d’effort des locataires du parc privé parisien en 2022 - if_ina_220

Données - INSEE

Figure 1 : quartiers regroupés en 14 zones Olap

Code
fig1 |>
  arrange(zone_olap, quartier_num) |>
  group_by(zone_olap) |>
  summarise(quartiers = paste(quartier_libelle, collapse = ", "), .groups = "drop") |>
  rename(`Zone Olap` = zone_olap, `Quartiers` = quartiers) |>
  gt() |>
  tab_header(title = "Regroupement des quartiers parisiens en 14 zones définies par l'Olap") |>
  cols_width(`Zone Olap` ~ px(90), `Quartiers` ~ px(700))
Regroupement des quartiers parisiens en 14 zones définies par l'Olap
Zone Olap Quartiers
1 Notre-Dame-des-Champs, Saint-Thomas-d’Aquin, Invalides, École militaire, Gros Caillou
2 Saint-Germain-l’Auxerrois, Palais Royal, Place Vendôme, Gaillon, Saint-Merri, Arsenal, Notre-Dame, Monnaie, Odéon, Saint-Germain-des-Prés, Champs-Élysées, Faubourg du Roule, Madeleine, Chaussée d’Antin
3 Europe, Muette, Porte Dauphine, Chaillot
4 Vivienne, Mail, Bonne Nouvelle, Arts et métiers, Enfants rouges, Archives, Sainte-Avoie, Saint-Gervais, Saint-Victor, Val de Grace, Sorbonne
5 Halles, Saint-Georges, Faubourg Montmartre, Rochechouart, Saint-Vincent-de-Paul, Porte Saint-Denis, Croulebarbe, Montparnasse
6 Necker, Ternes, Plaine de Monceaux
7 Grenelle, Javel, Auteuil
8 Saint-Lambert
9 Picpus, Grandes carrières, Clignancourt
10 Jardin des Plantes, Saint-Ambroise, Sainte-Marguerite, Salpêtrière, Petit-Montrouge, Batignolles
11 Porte Saint-Martin, Hôpital Saint-Louis, Folie Méricourt, Roquette, Quinze-Vingts, Parc de Montsouris, Epinettes, Goutte d’Or, Belleville
12 Maison-Blanche, Plaisance
13 Gare, La Chapelle, Villette, Pont de Flandres, Amérique, Saint-Fargeau, Charonne
14 Bel-Air, Bercy, Combat, Père Lachaise

Figure 2 : loyer moyen par zone

Code
fig2 |>
  mutate(zone = factor(zone, levels = zones_levels),
         zone_paris = if_else(zone == "Paris", "Paris", "Zone")) |>
  ggplot(aes(x = zone, y = loyer_moyen, fill = zone_paris)) +
  geom_col() +
  geom_text(aes(label = round(loyer_moyen)), vjust = -0.4, size = 3.5) +
  scale_fill_manual(values = c("Zone" = "#1B3F8B", "Paris" = "#B8860B"), guide = "none") +
  theme_minimal(base_size = 13) +
  labs(x = "Zone Olap", y = NULL,
       title = "Loyer moyen des logements loués vides dans le parc privé parisien",
       subtitle = "selon les zones définies par l'Olap, en 2022 (en euros)") +
  theme(panel.grid.minor = element_blank(),
        panel.grid.major.x = element_blank())

Figure 3 : répartition des ménages locataires selon le taux d’effort brut

Code
niveaux_taux_effort <- c("Inférieur à 21 %", "De 21 % à moins de 29 %",
                          "De 29 % à moins de 40 %", "De 40 % à moins de 67 %",
                          "Égal ou supérieur à 67 %")

fig3 |>
  select(categorie_menage, all_of(niveaux_taux_effort)) |>
  mutate(categorie_menage = factor(categorie_menage,
                                    levels = rev(c("Homme seul", "Femme seule",
                                                    "Famille monoparentale",
                                                    "Couple sans enfant",
                                                    "Couple avec enfant(s)",
                                                    "Ménage complexe", "Ensemble")))) |>
  pivot_longer(-categorie_menage, names_to = "taux_effort", values_to = "part") |>
  mutate(taux_effort = factor(taux_effort, levels = niveaux_taux_effort)) |>
  ggplot(aes(x = categorie_menage, y = part, fill = taux_effort)) +
  geom_col(position = position_stack(reverse = TRUE)) +
  geom_text(aes(label = part), position = position_stack(vjust = 0.5, reverse = TRUE),
            size = 3, color = "white") +
  coord_flip() +
  scale_fill_manual(values = c("#1B3F8B", "#3E6FBF", "#8FB0DE", "#E8737A", "#B8860B"),
                     name = "Taux d'effort brut") +
  guides(fill = guide_legend(nrow = 2)) +
  theme_minimal(base_size = 13) +
  labs(x = NULL, y = NULL,
       title = "Répartition des ménages locataires du parc privé parisien",
       subtitle = "selon le taux d'effort brut en 2022 (en %)") +
  theme(legend.position = "bottom",
        panel.grid.minor = element_blank(),
        panel.grid.major.y = element_blank())

Figure encadré : évolution des loyers et de l’ICC/IRL depuis 1987

Linéaire

Code
lois <- fig_encadre |>
  filter(!is.na(lois)) |>
  select(annee, lois)

fig_encadre |>
  mutate(indice_reglementaire = coalesce(icc, irl)) |>
  select(annee, `Loyers du parc privé parisien` = loyers_paris,
         `Indice de référence (ICC puis IRL)` = indice_reglementaire) |>
  pivot_longer(-annee, names_to = "serie", values_to = "indice") |>
  ggplot(aes(x = annee, y = indice, color = serie)) +
  geom_vline(data = lois, aes(xintercept = annee), linetype = "dashed", color = "grey70") +
  geom_line(linewidth = 1.1) +
  scale_color_manual(values = c("Loyers du parc privé parisien" = "#B8860B",
                                 "Indice de référence (ICC puis IRL)" = "#1B3F8B")) +
  theme_minimal(base_size = 13) +
  labs(x = NULL, y = NULL, color = NULL,
       title = "Évolution des loyers et de l'indice de référence",
       subtitle = "ICC (1987-2005) puis IRL (2006-2023) ; indice base 100 en 1987") +
  theme(legend.position = "bottom",
        panel.grid.minor = element_blank())

Echelle log

Code
lois <- fig_encadre |>
  filter(!is.na(lois)) |>
  select(annee, lois)

fig_encadre |>
  mutate(indice_reglementaire = coalesce(icc, irl)) |>
  select(annee, `Loyers du parc privé parisien` = loyers_paris,
         `Indice de référence (ICC puis IRL)` = indice_reglementaire) |>
  pivot_longer(-annee, names_to = "serie", values_to = "indice") |>
  ggplot(aes(x = annee, y = indice, color = serie)) +
  geom_vline(data = lois, aes(xintercept = annee), linetype = "dashed", color = "grey70") +
  geom_line(linewidth = 1.1) +
  scale_color_manual(values = c("Loyers du parc privé parisien" = "#B8860B",
                                 "Indice de référence (ICC puis IRL)" = "#1B3F8B")) +
  theme_minimal(base_size = 13) +
  scale_y_log10(breaks = scales::breaks_log(n = 8)) +
  labs(x = NULL, y = NULL, color = NULL,
       title = "Évolution des loyers et de l'indice de référence",
       subtitle = "ICC (1987-2005) puis IRL (2006-2023) ; indice base 100 en 1987") +
  theme(legend.position = "bottom",
        panel.grid.minor = element_blank())

Figure complémentaire 1 : indicateurs clés selon le type de ménage

Code
fig_comp1 |>
  rename(`Type de ménage` = type_menage,
         `Répartition (%)` = repartition_menages,
         `Revenu disponible médian (€)` = revenu_disponible_median,
         `Loyer brut médian (€)` = loyer_brut_median,
         `Loyer net médian (€)` = loyer_net_median,
         `Taux d'effort brut médian (%)` = taux_effort_brut_median,
         `Taux d'effort net médian (%)` = taux_effort_net_median,
         `Bénéficiaires d'aides (%)` = part_beneficiaires_aides,
         `Répartition des bénéficiaires (%)` = repartition_beneficiaires_aides) |>
  gt() |>
  tab_header(title = "Indicateurs clés selon le type de ménage")
Indicateurs clés selon le type de ménage
Type de ménage Répartition (%) Revenu disponible médian (€) Loyer brut médian (€) Loyer net médian (€) Taux d'effort brut médian (%) Taux d'effort net médian (%) Bénéficiaires d'aides (%) Répartition des bénéficiaires (%)
Homme seul 26.8 2290 850 840 38.4 36.5 16.3 25.7
Femme seule 31.6 2130 860 830 41.6 39.3 20.5 38.0
Famille monoparentale 6.3 3080 1260 1220 39.1 36.6 21.1 7.8
Couple sans enfant 19.6 4510 1140 1130 25.7 25.1 14.1 16.2
Couple avec enfant(s) 11.8 6360 1570 1550 24.4 23.9 10.2 7.1
Ménage complexe 3.9 4020 1110 1070 26.7 25.3 22.2 5.2
Ensemble 100.0 2750 980 960 33.9 32.6 17.0 100.0

Figure complémentaire 2 : indicateurs clés selon la zone Olap

Code
fig_comp2 |>
  mutate(zone = factor(zone, levels = zones_levels)) |>
  arrange(zone) |>
  rename(`Zone Olap` = zone,
         `Revenu disponible médian (€)` = revenu_disponible_median,
         `Loyer brut médian (€)` = loyer_brut_median,
         `Loyer net médian (€)` = loyer_net_median,
         `Taux d'effort brut médian (%)` = taux_effort_brut_median,
         `Taux d'effort net médian (%)` = taux_effort_net_median) |>
  gt() |>
  tab_header(title = "Indicateurs clés selon la zone Olap")
Indicateurs clés selon la zone Olap
Zone Olap Revenu disponible médian (€) Loyer brut médian (€) Loyer net médian (€) Taux d'effort brut médian (%) Taux d'effort net médian (%)
1 3970 1350 1350 32.7 31.8
2 3810 1300 1280 33.8 33.1
3 4340 1450 1440 31.3 30.7
4 3300 1120 1110 32.6 31.9
5 3090 1010 990 31.0 30.3
6 3750 1200 1190 31.3 30.5
7 3290 1100 1090 31.5 30.4
8 2970 670 950 31.1 30.3
9 2780 900 880 31.2 30.3
10 3030 990 970 30.7 29.8
11 2820 900 880 31.2 30.1
12 2890 960 940 32.3 31.3
13 2650 780 760 28.8 27.2
14 3030 900 890 29.0 28.0
Paris 3030 970 960 31.0 30.0

Figure complémentaire 3 : encadrement des loyers par zone

Code
fig_comp3 |>
  filter(zone != "Paris") |>
  mutate(zone = factor(zone, levels = zones_levels)) |>
  select(zone, `Loyer inférieur au loyer minoré` = part_inf_minore,
         `Loyer dans la fourchette` = part_fourchette,
         `Loyer supérieur au loyer majoré` = part_sup_majore) |>
  pivot_longer(-zone, names_to = "categorie", values_to = "part") |>
  mutate(categorie = factor(categorie, levels = c("Loyer inférieur au loyer minoré",
                                                    "Loyer dans la fourchette",
                                                    "Loyer supérieur au loyer majoré"))) |>
  ggplot(aes(x = zone, y = part, fill = categorie)) +
  geom_col(position = position_stack(reverse = TRUE)) +
  scale_fill_manual(values = c("#1B3F8B", "#8FB0DE", "#E8737A"), name = NULL) +
  theme_minimal(base_size = 13) +
  labs(x = "Zone Olap", y = NULL,
       title = "Part des locataires dépensant en 2022 un loyer inférieur au loyer minoré,",
       subtitle = "supérieur au loyer majoré ou compris dans la fourchette, par zone Olap (en %)") +
  theme(legend.position = "bottom",
        panel.grid.minor = element_blank(),
        panel.grid.major.x = element_blank())