💰💌 Si tu te procures un abonnement d'un an au forfait premium de Oui, mais je LLM d'ici le 30 novembre, je t'offre en prime mes quatre formations autodidactes, une valeur de 276 $ ! Clique ici !" 💰💌

Potion Bottle Icon Manuel d'alchimie du code Potion Bottle Icon

Analysons les données canadiennes de prix des logements

- 537 mots - Temps de lecture estimé: 3 minutes

Visiblement, notre premier ministre n’est pas très au courant du marché locatif québécois et des prix des logements. Voici donc les données les plus à jour (octobre 2019) sur le marché canadien du logement, tirées du site de la SCHL et nettoyées pour les rendre utilisables et visualisables !

🌘 Outils utilisés

Nous allons utiliser le langage R et les librairies tidyverse, sf et mapsf.

library(tidyverse)
library(sf)
library(mapsf)

🌘 Données de prix des logements de la SCHL

🌘 Lecture des données

Les données de prix des logements sont dans un fichier Excel XLSX, et comme tout bon fichier provenant d’une agence du gouvernement, contient des métadonnées, des cellules fusionnées, des titres avec des caractères invalides, des sous-totaux mal identifiés …

Le tableau commence à la ligne 4, nous allons donc éliminer les trois premières lignes.

urban_rental <-
  readxl::read_xlsx("urban-rental-market-survey-data-average-rents-urban-centres-2019.xlsx",
                    skip = 3)

On renomme les colonnes pour les rendre utilisables avec R

colnames(urban_rental) <- c(
  "province",
  "centre",
  "subdiv_recens",
  "type_logement",
  "bachelor",
  "",
  "chambre_1",
  "",
  "chambre_2",
  "",
  "chambre_3",
  "",
  "total",
  ""
)
On traite ici d'un seul coup avec une séquence d'opérateurs l'ensemble des anomalies dans les données. Je vais commenter cette section directement dans le code.

#' Traiter les données de location urbaine
#'
#' Cette fonction traite les données de location urbaine en sélectionnant les variables pertinentes,
#' en pivotant les données, en extrayant les valeurs numériques, en filtrant et en formatant.
#'
#' @param urban_rental Un dataframe contenant les données de location urbaine
#' @return Un dataframe traité
traiter_donnees_location_urbaine <- function(urban_rental) {
  urban_rental %>%
    selectionner_variables_pertinentes() %>%
    pivoter_et_extraire_numerique() %>%
    filtrer_et_formater_donnees() %>%
    pivoter_large_et_selectionner_final()
}

#' Sélectionner les variables pertinentes des données de location urbaine
#'
#' @param data Un dataframe contenant les données de location urbaine
#' @return Un dataframe avec les variables sélectionnées
selectionner_variables_pertinentes <- function(data) {
  data %>%
    select(
      province,
      centre,
      subdiv_recens,
      type_logement,
      bachelor,
      chambre_1,
      chambre_2,
      chambre_3
    )
}

#' Pivoter les données et extraire les valeurs numériques
#'
#' @param data Un dataframe avec les variables sélectionnées
#' @return Un dataframe avec les données pivotées et les valeurs numériques extraites
pivoter_et_extraire_numerique <- function(data) {
  data %>%
    pivot_longer(
      c(bachelor, chambre_1, chambre_2, chambre_3),
      names_to = "nombre_pieces",
      values_to = "loyer_moyen"
    ) %>%
    # Extraire le montant numérique du montant indiqué avec un signe de $ devant le nombre
    mutate(loyer_moyen_num = loyer_moyen %>%
             str_extract_all("\\d+") %>%
             as.numeric()) %>%
    select(-loyer_moyen)
}

#' Filtrer et formater les données
#'
#' @param data Un dataframe avec les données pivotées et les valeurs numériques extraites
#' @return Un dataframe filtré et formaté
filtrer_et_formater_donnees <- function(data) {
  data %>%
    # Supprimer les lignes avec des montants manquants
    filter(!is.na(loyer_moyen_num)) %>%
    # Supprimer les sous-totaux par division de recensement
    filter(subdiv_recens != "Total") %>%
    # Conserver seulement le total des types de logements (essentiellement, rangée ou bloc, peu important pour nos analyses)
    filter(type_logement == "Total") %>%
    # Formater les subdivisions de recensement comme Statistiques Canada et extraire le genre qui est entre parenthèses dans une autre variable
    mutate(
      subdiv_genre = subdiv_recens %>%
        str_match(pattern = "(.*)\\s+\\((.*)\\)") %>%
        `[`(, 3),
      subdiv_recens = subdiv_recens %>%
        str_match(pattern = "(.*)\\s+\\((.*)\\)") %>%
        `[`(, 2)
    )
}

#' Pivoter les données en format large et sélectionner les colonnes finales
#'
#' @param data Un dataframe filtré et formaté
#' @return Le dataframe final traité
pivoter_large_et_selectionner_final <- function(data) {
  data %>%
    # Ramener au format large puisque notre clé sera la région géographique pour fusionner avec les données spatiales
    pivot_wider(names_from = "nombre_pieces", values_from = "loyer_moyen_num") %>%
    select(
      province,
      centre,
      subdiv_genre,
      subdiv_recens,
      type_logement,
      bachelor,
      chambre_1,
      chambre_2,
      chambre_3
    )
}

# Exécution principale
urban_rental_pivot <- traiter_donnees_location_urbaine(urban_rental)

🌘 Subdivisions derecensement

Nous importons maintenant les données de subdivisions de recensement

lsdr000b16a_f <- sf::read_sf("lsdr000b16a_f/lsdr000b16a_f.shp")
lsdr000b16a_f[lsdr000b16a_f$SDRIDU == "4810039",]$SDRNOM <- "Lloydminster (Alta Part)"
lsdr000b16a_f[lsdr000b16a_f$SDRIDU == "4717029",]$SDRNOM <- "Lloydminster (Sask Part)"

Comme la ville de Lloydminster qui chevauche l’Alberta et la Saskatchewan est identifiée différemments dans les données de la SCHL que dans celles de Statistiques Canada, on fait la correction ici pour permettre la fusion, qui se fait sur le nom de la subdivision au lieu d’utiliser l’identifiant unique SDRIDU, car la SCHL ne l’a pas fourni dans ses données (ce qui serait une bonne pratique).

Validons qu’on a bien tout suite à ces corrections:

is.na(setdiff(
  unique(urban_rental_pivot$subdiv_recens),
  unique(lsdr000b16a_f$SDRNOM)
))
## [1] FALSE  TRUE

On peut maintenant fusionner les données

urban_rental_sf <- lsdr000b16a_f %>%
  inner_join(urban_rental_pivot,
             by = c("SDRNOM" = "subdiv_recens",
                    "SDRGENRE" = "subdiv_genre")) %>%
  select(
    PRIDU,
    PRNOM,
    centre,
    SDRIDU,
    SDRGENRE,
    SDRNOM,
    bachelor,
    chambre_1,
    chambre_2,
    chambre_3,
    geometry
  ) %>%
  distinct()

Exportons ensuite les données au format GeoJSON pour consommation ultérieure.

urban_rental_sf %>% sf::write_sf("urban_rental_sf.geojson") system("gzip urban_rental_sf.geojson")

Vous pouvez obtenir le fichier de données GeoJSON compressé ici: urban_rental_sf.geojson.gz

🌘 Analyse du prix des logements au Québec

Voyons voir ce qu’il se passe à Montréal:

urban_rental_sf %>%
  filter(centre=="Montréal" & SDRNOM=="Montréal") %>%
  select(centre,SDRNOM,bachelor,chambre_1,chambre_2,chambre_3) %>% 
  st_drop_geometry()
## # A tibble: 1 x 6
##   centre   SDRNOM   bachelor chambre_1 chambre_2 chambre_3
## * <chr>    <chr>       <dbl>     <dbl>     <dbl>     <dbl>
## 1 Montréal Montréal      660       752       851      1118

Le prix moyen d’un appartement d’une chambre, communément appelé un 3 1/2, est de 752$ en octobre 2019. Soit 50% plus cher que l’estimation la plus basse du premier ministre.

Voyons maintenant où il est possible d’obtenir un logement 3 1/2 à moins de 500$ au Québec

srd_moins_500_ch1 <- urban_rental_sf %>%
  filter(chambre_1<=500 & PRNOM=="Quebec / Québec") %>%
  select(SDRNOM,chambre_1) %>% 
  arrange(desc(chambre_1)) 
srd_moins_500_ch1 %>% 
  st_drop_geometry()
## # A tibble: 23 x 2
##    SDRNOM          chambre_1
##  * <chr>               <dbl>
##  1 Montmagny             491
##  2 Victoriaville         487
##  3 Sorel-Tracy           486
##  4 Saguenay              486
##  5 Matane                482
##  6 Rawdon                478
##  7 Magog                 476
##  8 Sainte-Marie          472
##  9 Rivière-du-Loup       460
## 10 Mont-Laurier          457
## # … with 13 more rows
nb_subdivisions_qc <- urban_rental_sf %>% 
  st_drop_geometry() %>% 
  filter(PRNOM=="Quebec / Québec") %>% 
  select(SDRNOM) %>% 
  distinct() %>% 
  count()

Il y a 130 subdivisions de recensement urbaines au Québec, et 23 d’entre elles, soit 18 %, ont un coût moyen de moins de 500$ pour un appartement d’une chambre.

Visualisons le coût moyen des 3 1/2 pour toutes les subdivisions de recensement urbaines du Québec

urban_rental_sf %>%
  filter(PRNOM=="Quebec / Québec") %>%
  select(SDRIDU, chambre_1) %>% 
  mf_map(var = "chambre_1", type = "choro")

Carte de visualisation des prix des logements au Canada

Allons maintenant voir le centre démographique de Montréal:

donnees_vis_ch1 <- urban_rental_sf %>%
  filter(centre=="Montréal") %>%
  select(SDRIDU, chambre_1) %>% 
  mf_map(var = "chambre_1", type = "choro")

Graphique de l'évolution des prix des logements au fil du temps

Et celui de Québec:

donnees_vis_ch1 <- urban_rental_sf %>%
  filter(centre=="Québec") %>%
  select(SDRIDU, chambre_1) %>% 
  mf_map(var = "chambre_1", type = "choro")

Analyse comparative des prix des logements entre les provinces canadiennes

🌘 Sources

Shooting Stars IconConsultation ExpressShooting Stars Icon

Bénéficie d'une heure de consultation dédiée avec François pour résoudre tes défis informatiques et stratégiques. Que ce soit pour la migration vers des technologies libres, la sécurisation de tes systèmes, la documentation de tes procédures, la conception de petits systèmes ou l'automatisation de tâches, cette session intensive t'offre des solutions concrètes et un plan d'action clair.

Tu seras libre ensuite de poursuivre avec un forfait de consultation sur mesure ou les programmes DéconstruIT ou Pleine Confiance

Découvre la Consultation Express.
Abonne-toi au fil RSS pour ne rien manquer.

Étiquettes