Réutilisation automatique des données de Météo France

Pour un de mes projets en cours, j’avais besoin de données météorologiques qui puissent être mises régulièrement à jour. Je présente ici quelques astuces pour tirer pleinement parti de notre ami R et de ses multiples packages :

  • récupérer des données publiques automatiquement, sans avoir à télécharger manuellement les fichiers .csv
  • les mettre en forme avec dplyr et tidyr
  • les représenter dans une carte interactive avec leaflet
  • mettre un tableau différent dans une fenêtre popup pour chaque point de la carte avec leafpop (on peut mettre aussi des graphiques, mais comme c’est en cours de développement, la fonctionnalité à encore quelques bugs, je préfère ne pas la mettre ici pour l’instant)
  • notez que j’utilise ici le nouveau pipe |> (pour %>%) et le raccourci \(x) (pour function(x)) de R 4.0

Remarque : il faut une bonne connexion internet pour que le téléchargement ne prenne pas trop de temps (ou modifier options(timeout = 60) - le comportement par défaut signifie qu’au-delà de 60 secondes, le téléchargement est interrompu automatiquement par R).

Voici le code par étape :

Import des données

D’abord on charge les packages dont on aura besoin.

# chargement des packages
library(dplyr)
library(tidyr)
library(echarts4r)
library(leaflet)
library(leafpop)
## Warning in CPL_gdal_init(): GDAL Error 1: libarrow_dataset.so.1000: Ne peut
## ouvrir le fichier d'objet partagé: Aucun fichier ou dossier de ce type

## Warning in CPL_gdal_init(): GDAL Error 1: libarrow_dataset.so.1000: Ne peut
## ouvrir le fichier d'objet partagé: Aucun fichier ou dossier de ce type
## Warning in CPL_gdal_init(): GDAL Error 1: libarrow.so.1000: Ne peut ouvrir le
## fichier d'objet partagé: Aucun fichier ou dossier de ce type

## Warning in CPL_gdal_init(): GDAL Error 1: libarrow.so.1000: Ne peut ouvrir le
## fichier d'objet partagé: Aucun fichier ou dossier de ce type
## Warning in CPL_gdal_init(): GDAL Error 1: libarrow_dataset.so.1000: Ne peut
## ouvrir le fichier d'objet partagé: Aucun fichier ou dossier de ce type

## Warning in CPL_gdal_init(): GDAL Error 1: libarrow_dataset.so.1000: Ne peut
## ouvrir le fichier d'objet partagé: Aucun fichier ou dossier de ce type
## Warning in CPL_gdal_init(): GDAL Error 1: libarrow.so.1000: Ne peut ouvrir le
## fichier d'objet partagé: Aucun fichier ou dossier de ce type

## Warning in CPL_gdal_init(): GDAL Error 1: libarrow.so.1000: Ne peut ouvrir le
## fichier d'objet partagé: Aucun fichier ou dossier de ce type

Ensuite, on récupère les données gratuites de Météo-France. Je suis passée par ce lien : donneespubliques.meteofrance.fr. Il est important de respecter la licence de ces données (paragraphe : Condition d’accès), c’est à dire de les sourcer correctement si on les réutilise.

Les données qui m’intéressent sont les suivantes :

  • les données concernant les stations météorologiques (contenant leurs coordonnées en particulier)
  • les données mensuelles de suivi météo

Les premières sont faciles à récupérer, il suffit de copier le lien csv (clic droit > copier le lien) de la liste des stations essentielles.

Les secondes sont un peu plus retorses, car le lien de téléchargement n’est pas accessible en faisant un clic droit sur le bouton “télécharger”. De plus, elles sont compressées avec gzip et ne sont pas directement sous format csv.

Pour trouver le lien de téléchargement, il faut cliquer sur le bouton “télécharger”, puis annuler l’ouverture du fichier.

Le lien qui termine en .csv.gz à copier (clic droit) se trouve ici :

Nous remarquerons que les fichiers sont nommés avec le format climat.aaaamm (par exemple, 202103 pour mars 2021), et nous pouvons en profiter pour en déduire le nom des autres fichiers, sans avoir à faire la même manipulation pour chacun des mois qui nous intéresse.

C’est maintenant que l’on peut faire un test d’import des données dans R pour un seul mois :

# Test
# données stations :
read.csv2("https://donneespubliques.meteofrance.fr/donnees_libres/Txt/Synop/postesSynop.csv") |> head() # ici est le premier lien copié
ID Nom Latitude Longitude Altitude
7005 ABBEVILLE 50.136000 1.834000 69
7015 LILLE-LESQUIN 50.570000 3.097500 47
7020 PTE DE LA HAGUE 49.725167 -1.939833 6
7027 CAEN-CARPIQUET 49.180000 -0.456167 67
7037 ROUEN-BOOS 49.383000 1.181667 151
7072 REIMS-PRUNAY 49.209667 4.155333 95

# données suivi météo pour mai 2020
readr::read_delim("https://donneespubliques.meteofrance.fr/donnees_libres/Txt/Climat/climat.202005.csv.gz", col_select = c("NUM_POSTE", "DAT", "TMMOY", "RR")) |> # read_delim décopmresse automatiquement le fichier .csv.gz en .csv !
  head() # pour l'exemple, je ne montre que les 6 premières lignes et les 4 colonnes qui nous intéressent
NUM_POSTE DAT TMMOY RR
07005 2020-05-01 13.6 27
07015 2020-05-01 14.7 4
07020 2020-05-01 12.6 29
07027 2020-05-01 13.3 42
07037 2020-05-01 14.2 34
07072 2020-05-01 13.9 23

Ok, ça fonctionne ! Maintenant, je voudrais automatiser l’import des données de suivi pour les printemps des années 2018 à 2020 en métropole (hé, pourquoi pas ?).

Voici une fonction simple qui va m’aider.

# fonction pour lister les mois qui m'intéressent au format aaaamm
# annees : vecteur d'années
lister_dates <- \(annees) paste0(
    rep(annees, each = 3),
    rep(c("03", "04", "05"), times = length(annees)) # les données de mars, avril et mai seulement ; attention les "0" comptent !
  )

# exemple
lister_dates(2018:2020)
## [1] "201803" "201804" "201805" "201903" "201904" "201905" "202003" "202004"
## [9] "202005"

Et voici maintenant l’import en tant que tel :

# Import
meteo <- lister_dates(2018:2020) %>% # choisis les années à importer (possibilité de 1990 à 2020)
  sprintf("https://donneespubliques.meteofrance.fr/donnees_libres/Txt/Climat/climat.%s.csv.gz", .) |>
  readr::read_delim(col_select = c("NUM_POSTE", "DAT", "TMMOY", "RR")) |>
  inner_join( # importe les infos des stations météo (ville et coordonnées géographiques)
    readr::read_delim("https://donneespubliques.meteofrance.fr/donnees_libres/Txt/Synop/postesSynop.csv"),
    by = c("NUM_POSTE" = "ID") # nom de la colonne permettant de faire le lien entre les 2 tables
  ) |>
  as_tibble() |> # transforme en tibble pour un plus joli format de sortie
  dplyr::filter(Latitude > 25) |> # conserve uniquement les stations métropole (élimine outre-mer)
  mutate(
    DAT = as.Date(DAT), # passe la date en format Date
    Mois = format(DAT, format = "%m/%Y") # récupère les mois/années
  )

head(meteo)
NUM_POSTE DAT TMMOY RR Nom Latitude Longitude Altitude Mois
07005 2018-03-01 5.8 70 ABBEVILLE 50.13600 1.834000 69 03/2018
07015 2018-03-01 5.6 67 LILLE-LESQUIN 50.57000 3.097500 47 03/2018
07020 2018-03-01 7.5 108 PTE DE LA HAGUE 49.72517 -1.939833 6 03/2018
07027 2018-03-01 6.5 61 CAEN-CARPIQUET 49.18000 -0.456167 67 03/2018
07037 2018-03-01 5.6 110 ROUEN-BOOS 49.38300 1.181667 151 03/2018
07072 2018-03-01 5.6 50 REIMS-PRUNAY 49.20967 4.155333 95 03/2018

Carte température

# Passage des données de température en format court pour les afficher dans la carte
table_temp <- meteo |>
  pivot_wider(id_cols = Longitude:Nom, names_from = "Mois", values_from = "TMMOY")

head(table_temp)
Longitude Latitude Nom 03/2018 04/2018 05/2018 03/2019 04/2019 05/2019 03/2020 04/2020 05/2020
1.834000 50.13600 ABBEVILLE 5.8 12.0 14.3 8.8 10.3 12.3 7.3 12.4 13.6
3.097500 50.57000 LILLE-LESQUIN 5.6 12.7 15.9 9.0 10.9 12.6 7.3 12.8 14.7
-1.939833 49.72517 PTE DE LA HAGUE 7.5 10.8 12.4 9.8 10.1 12.2 8.8 11.0 12.6
-0.456167 49.18000 CAEN-CARPIQUET 6.5 11.4 13.3 8.9 9.6 11.9 7.8 11.9 13.3
1.181667 49.38300 ROUEN-BOOS 5.6 12.0 14.4 8.5 10.1 11.9 7.1 13.2 14.2
4.155333 49.20967 REIMS-PRUNAY 5.6 12.4 15.5 8.2 9.8 11.9 7.3 12.3 13.9
# Créé et affiche la carte des données de température
leaflet(data = table_temp, options = leafletOptions(maxZoom = 9), width = "100%") |> # initialise la carte
  addProviderTiles("Stamen.Watercolor") |> # ajoute un fond de carte (source : http://maps.stamen.com/#watercolor)
  addMarkers( # ajoute les points représentant les stations
    ~Longitude,
    ~Latitude,
    popup = popupTable(table_temp, row.numbers = FALSE, feature.id = FALSE, zcol = 3:12), # la table de température apparaît quand on clique sur la station
    icon = list(iconUrl = "cloud-sun-rain-solid.svg", iconSize = c(30,30)) # icone personnalisée
  )

Carte pluviométrie

# Passage des données de pluviométrie en format court pour les afficher dans la carte
table_pluvio <- meteo |>
  pivot_wider(id_cols = Longitude:Nom, names_from = "Mois", values_from = "RR")

head(table_pluvio)
Longitude Latitude Nom 03/2018 04/2018 05/2018 03/2019 04/2019 05/2019 03/2020 04/2020 05/2020
1.834000 50.13600 ABBEVILLE 70 71 60 56 40 24 75 29 27
3.097500 50.57000 LILLE-LESQUIN 67 48 85 81 35 32 66 41 4
-1.939833 49.72517 PTE DE LA HAGUE 108 40 21 49 31 30 69 25 29
-0.456167 49.18000 CAEN-CARPIQUET 61 109 46 39 40 48 44 53 42
1.181667 49.38300 ROUEN-BOOS 110 73 61 64 43 48 66 25 34
4.155333 49.20967 REIMS-PRUNAY 50 31 36 34 20 64 53 30 23
# Créé et affiche la carte des données de pluviométrie
leaflet(data = table_pluvio, options = leafletOptions(maxZoom = 9), width = "100%") |>
  addProviderTiles("Stamen.Watercolor") |>
  addMarkers(
    ~Longitude,
    ~Latitude,
    popup = popupTable(table_pluvio, row.numbers = FALSE, feature.id = FALSE, zcol = 3:12),
    icon = list(iconUrl = "cloud-sun-rain-solid.svg", iconSize = c(30,30))
  )

Et voilà le travail ! N’oubliez pas de cliquer sur les stations pour voir apparaître les données ☺

Anna Doizy
Anna Doizy
Chercheuse, consultante et formatrice freelance
Libre comme l’R

Méthodologie scientifique et analyses de données statistiques