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)
(pourfunction(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 ☺