--- title: "Concentration de CO2 dans l'atmosphère depuis 1958" author: "GuR" date: "23/09/2025" output: html_document: default pdf_document: default subtitle: "Sujet 1 - Exercice 03 - Module 03" --- ```{r setup, include=FALSE} knitr::opts_chunk$set(echo = TRUE) ``` # Récupération & aperçus des données ```{r} data_url = "monthly_in_situ_co2_mlo.csv" # [ 1958 ; 2025 ] # Source = https://scrippsco2.ucsd.edu/assets/data/atmospheric/stations/in_situ_co2/monthly/monthly_in_situ_co2_mlo.csv ``` ```{r echo=FALSE} data = read.csv(data_url, skip = 61) # skip = ignorer la 1ère ligne du CSV qui contient un commentaire head(data) #affichage du début du jeu de données ``` ```{r echo=FALSE} tail(data) # affichage de la fin du jeu de données ``` ## Organisation du fichier de données ### En-tête ``` ------------------------------------------------------------------------------------------- Atmospheric CO2 concentrations (ppm) derived from in situ air measurements at Mauna Loa, Observatory, Hawaii: Latitude 19.5°N Longitude 155.6°W Elevation 3397m Since December 2022 sampling has temporarily been relocated to MaunuaKea, Hawaii Latitude 19.8°N Longitude 155.5°W Elevation 4145m Source: R. F. Keeling, S. J. Walker, S. C. Piper and A. F. Bollenbacher Scripps CO2 Program ( http://scrippsco2.ucsd.edu ) Scripps Institution of Oceanography (SIO) University of California La Jolla, California USA 92093-0244 Status of data and correspondence: These data are subject to revision based on recalibration of standard gases. Questions about the data should be directed to Dr. Ralph Keeling (rkeeling@ucsd.edu), Stephen Walker (sjwalker@ucsd.edu) and Stephen Piper (scpiper@ucsd.edu), Scripps CO2 Program. Baseline data in this file through 09-Aug-2025 from archive dated 11-Aug-2025 17:08:37 ------------------------------------------------------------------------------------------- Please cite as: C. D. Keeling, S. C. Piper, R. B. Bacastow, M. Wahlen, T. P. Whorf, M. Heimann, and H. A. Meijer, Exchanges of atmospheric CO2 and 13CO2 with the terrestrial biosphere and oceans from 1978 to 2000. I. Global aspects, SIO Reference Series, No. 01-06, Scripps Institution of Oceanography, San Diego, 88 pages, 2001. If it is necessary to cite a peer-reviewed article, please cite as: C. D. Keeling, S. C. Piper, R. B. Bacastow, M. Wahlen, T. P. Whorf, M. Heimann, and H. A. Meijer, Atmospheric CO2 and 13CO2 exchange with the terrestrial biosphere and oceans from 1978 to 2000: observations and carbon cycle implications, pages 83-113, in "A History of Atmospheric CO2 and its effects on Plants, Animals, and Ecosystems " editors, Ehleringer, J.R., T. E. Cerling, M. D. Dearing, Springer Verlag, New York, 2005. ``` ### Contenu du jeu de données - Columns 1-4 give the dates in several redundant formats : Year (YYYY) | Mn = month | Date (Excel : 21200 ?) | Date.1 (YYYY.041 ?) - Column 5 | CO2 (ppm) | gives monthly Mauna Loa CO2 concentrations in micro-mol CO2 per mole (ppm), reported on the 2012 SIO manometric mole fraction scale. This is the standard version of the data most often sought. The monthly values have been adjusted to 24:00 hours on the 15th of each month. - Column 6 | CO2 seasonally adjusted (ppm) | gives the same data after a seasonal adjustment to remove the quasi-regular seasonal cycle. The adjustment involves subtracting from the data a 4-harmonic fit with a linear gain factor. - Column 7 | fit (ppm) | is a smoothed version of the data generated from a stiff cubic spline function plus 4-harmonic functions with linear gain. - Column 8 | fit seasonally adjusted (ppm) | is the same smoothed version with the seasonal cycle removed. - Column 9 | CO2 filled (ppm) | is identical to Column 5 except that the missing values from Column 5 have been filled with values from Column 7. - Column 10 | CO2 filled seasonally adjusted (ppm) | is identical to Column 6 except missing values have been filled with values from Column 8. Missing values are denoted by -99.99 - Column 11 | Sta | is the 3-digit sampling station identifier. MLO = Mauna Loa Observatory. MKO = the summit of nearby Maunakea. MKO data are used to a fill a gap created by the 2022 eruption of Mauna Loa, which led to the shutdown measurements by the Scripps CO2 program at MLO from Dec 2022 through Feb 2023 ### Commentaires sur les données : - CO2 concentrations are measured on the '12' calibration scale - UTILISER données de la colonne 9 "CO2 filled (ppm)" `data$CO2.1` # Rechercher les données manquantes éventuelles Lancer une fonction d'analyse des données, ligne par ligne, qui sélectionne celles dont la valeur est manquante. ```{r echo=FALSE} lignes_na = apply(data, 1, function(x) any(is.na(x))) # is.na "not available" / traverser le jeu de données (data) ligne par ligne et appliquer à chaque ligne la fonction (qui ) data[lignes_na,] # afficher le contenu des lignes sélectionnées ``` Masquer les lignes contenant des N/A ```{r echo=FALSE} data <- na.omit(data) ``` Certaines lignes comportent des données non significatives ("-99.99") : - 2 lignes de 01+02 1958 - 5 lignes de 08-12 2025 Ignorer ces lignes après la création d'une nouvelle colonne date (ci-dessous). Vérifier également le type de données : pour les colonnes "Yr" et "Mn" ```{r echo=FALSE} class(data$Yr) class(data$Mn) ``` # Vérification et inspection ## Pré-traitement des données Préparation du format date ```{r} library(parsedate) annee = 1995 mois = 06 ws_annee = paste(annee) # convertion en chaîne de caractères ws_mois = paste(mois) iso = as.Date(paste0(ws_annee, "-", ws_mois, "-01"), .format = "%Y-%m") as.character(parse_iso_8601(iso)) ``` Fonction pour appliquer cette transformation de format date à l'ensemble des dates du jeu de données ```{r} convert_month <- function (annee, mois) { # x = annee ws_annee = paste(annee) # convertion en chaîne de caractères ws_mois = paste(mois) iso = as.Date(paste0(ws_annee, "-", ws_mois, "-01"), .format = "%Y-%m") as.character(parse_iso_8601(iso)) # 1995-06-01 [UTC] } ``` Ajouter une nouvelle colonne "Date" dans le CSV avec les dates formatées : ```{r} # SAPPLY with multiple arguments # my_function <- function(x, factor, offset) { return((x * factor) + offset) } # numbers <- c(1, 2, 3, 4, 5) # result <- sapply(numbers, my_function, factor = 2, offset = 3) # Output: [1] 5 7 9 11 13 for (i in 1:length(data)) { data$date <- as.Date(convert_month(data$Yr, data$Mn)) } head(data) ``` ```{r echo=FALSE} class(data$date) ``` Ignorer les lignes de données non significatives (voir plus haut) : ```{r} # données "-99.99" de 01 à 02/1958 + de 08 à 12/2025 data <- subset(data,date > "1958-02-01" & date < "2025-08-01") ``` # 1. Graphique d'oscillation périodique & évolution systématique plus lente ## Evolution régulière année après années ```{r} data = data[order(data$date),] #tri chronologique with(data, plot(date, CO2.1, type="l", col="#f00a36")) # plot(abscisse, ordonnée, type) ``` ## Oscillation périodique annuelle Zoom sur les 50 derniers résultats ```{r} with(tail(data, 50), plot(date, CO2.1, type="l", main="Concentration de CO2 dans l'atmosphère", xlab="Dates", ylab="Concentration de CO2 (ppm)", # xlim=c(0,100), ylim=c(360,440), lwd = 2, col = "#52057f")) ``` Affichage par années ```{r} tab_annee <- subset(data, date >= "2020-01-01" & date < "2021-01-01") with(tab_annee, plot(date, CO2.1, type="l", main="Concentration de CO2 dans l'atmosphère en 2020", xlab="2020", ylab="Concentration de CO2 (ppm)", # xlim=c(0,100), ylim=c(360,440), lwd = 2, col = "orange")) ``` ## 2. Séparez ces deux phénomènes. Caractérisez l'oscillation périodique. Proposez un modèle simple de la contribution lente, estimez ses paramètres et tentez une extrapolation jusqu'à 2025 (dans le but de pouvoir valider le modèle par des observations futures) ### A/ Observation de l'oscillation périodique Mise en place d'une fonction pour traitement par années ```{r} data_annee <- function (annee) { # retourne l'ensemble des données d'une même année date_min = paste0(annee,"-01-01") # entre le 2020-01-01... date_max = paste0(annee+1,"-01-01") # ...et le 2021-01-01 subset(data, date >= date_min & date < date_max) } data_annee(2017) ``` Comparaison des années (entre 2020 et 2024), pour mise en évidence d'une ondulation récurrente : ```{r} periode <- c(2020:2024) for (i in 1:length(periode)) { tab <- data_annee(periode[i]) # Affichage du graphique annuel with(tab, plot(date, CO2.1, type="l", main = paste0("Concentration de CO2 dans l'atmosphère en ", periode[i]), xlab=periode[i], ylab="Concentration de CO2 (ppm)", # xlim=c(0,100), ylim=c(360,440), lty = 1, # type de traits, de 1 à 6 lwd = 2, #épaisseur du trait col = paste0("#ffc719")) ) } ``` ### Caractérisation de l’oscillation périodique - Croissance de janvier à mai - Concentration la + forte en **mai** de chaque année - Puis décroissance entre mai et septembre - Concentration la + faible en **septembre** ou **octobre** de chaque année - Puis croissance jusqu'en décembre ### Synthèse par années ```{r include=FALSE} #Trier par volume de concentration de CO2 décroissant au cours de l'année : #tab <- data_annee(1977) #data_order <- tab[order(tab$CO2.1, decreasing=TRUE),] ``` ```{r} moyenne_annuelle <- function (annee) { tab <- data_annee(annee) mean(as.numeric(tab$CO2.1), na.rm=TRUE) } max_annuel <- function (annee) { tab <- data_annee(annee) max(as.numeric(tab$CO2.1)) } min_annuel <- function (annee) { tab <- data_annee(annee) min(as.numeric(tab$CO2.1)) } ``` ### Modèle simple d'évolution Moyennes annuelles de concentration de CO2, avec valeurs maximales & minimales : ```{r} periode <- c(1959:2024) toutes_les_moyennes <- data.frame( Année = periode, Moy_CO2 = sapply(periode, moyenne_annuelle), Max = sapply(periode, max_annuel), Min = sapply(periode, min_annuel) ) head(toutes_les_moyennes) tail(toutes_les_moyennes) ``` Représentation graphique de l'évolution des moyennes annuelles de concentration de CO2 : ```{r} with(toutes_les_moyennes, plot(Année, Moy_CO2, type="p", main="Évolution des moyennes de concentration de CO2 dans l'atmosphère", xlab="Années", ylab="Concentration de CO2 (ppm)", lwd = 1, col = "#008374")) ``` On observe bien que la moyenne de concentration annuelle augmente chaque année. Qu'en est-il de la variation entre 2 années ? Calcul de la **variation annuelle** : ```{r} nb_lignes <- dim(toutes_les_moyennes)[1] # nombre de lignes / dim(x)[2] = nombre de colonnes / dim(x) = nb lignes, nb colonnes for (i in 2:nb_lignes) { diff <- toutes_les_moyennes$Moy_CO2[i] - toutes_les_moyennes$Moy_CO2[i-1] toutes_les_moyennes$Diff[i] <- diff } #toutes_les_moyennes$Diff ``` ```{r} with(toutes_les_moyennes, plot(Année, Diff, type="p", main="Évolution de la variation annuelle de concentration de CO2", xlab="Années", ylab="Variation annuelle (ppm)", lwd = 2, col = "#8a7967")) ``` Chaque année, la variation de la concentration de CO2 dans l'atmosphère entre 2 années tend à augmenter : de +0,93 en 1959 elle atteint +3,57 en 2025 Calcul de la **droite de régression linéaire** (médiane du nuage de points, définie par la méthode des moindres carrés) : ```{r} plot(toutes_les_moyennes$Année, toutes_les_moyennes$Diff, type="p", main="Évolution de la variation annuelle de concentration de CO2", xlab="Années", ylab="Variation annuelle (ppm)", pch = 16, cex = 1.3, col = "#8a7967" ) # Régression linéaire ==> lm(toutes_les_moyennes$Diff ~ toutes_les_moyennes$Année) abline(lm(toutes_les_moyennes$Diff ~ toutes_les_moyennes$Année), col="#00a4e4", lwd=2) ``` Tentative de prédiction pour 2030 (+6 ans) ```{r} var_diff <- toutes_les_moyennes$Diff var_annee <- toutes_les_moyennes$Année fit <- lm( var_diff ~ var_annee ) # modèle summary(fit) ``` ```{r} # nouveaux points = -56.452192 + 0.029176 (var_annee) newdata = data.frame(var_annee = c(2025,2026,2027,2028,2029,2030)) prediction <- predict(fit, newdata) prediction ``` => En 2030, le modèle prédit une variation de CO2 de 2.78 par rapport à l'année précédente. ```{r} annee = 2024 ligne <- which(grepl(annee, toutes_les_moyennes$Année)) CO2_predict <- toutes_les_moyennes$Moy_CO2[ligne] + prediction CO2_predict ``` => En 2030, le modèle prédit une concentration moyenne de CO2 dans l'atmosphère de **427.12 ppm**.