--- title: "Concentration de CO2 dans l'atmosphère depuis 1958" author: "Hélène Raynal" date: "21 avril 2020" output: html_document --- ### Sujet En 1958, Charles David Keeling a initié une mesure de la concentration de CO2 dans l'atmosphère à l'observatoire de Mauna Loa, Hawaii, États-Unis qui continue jusqu'à aujourd'hui. L'objectif initial était d'étudier la variation saisonnière, mais l'intérêt s'est déplacé plus tard vers l'étude de la tendance croissante dans le contexte du changement climatique. En honneur à Keeling, ce jeu de données est souvent appelé "Keeling Curve" (voir (https://en.wikipedia.org/wiki/Keeling_Curve) pour l'histoire et l'importance de ces données). Les données sont disponibles sur le site Web de l' [Institut Scripps](https://scrippsco2.ucsd.edu/) . J'ai utilisé par erreur les observations mensuelles (je n'ai pas le temps de refaire tout le travail en utilisant les données hebdomadaires, ce sont d'ailleurs les données mensuelles qui sont utilisées en général dans les études d'impact climatiques ) [observations mensuelles](https://scrippsco2.ucsd.edu/assets/data/atmospheric/stations/in_situ_co2/monthly/monthly_in_situ_co2_mlo.csv). Attention, ce fichier est mis à jour régulièrement avec de nouvelles observations. Notez donc bien la date du téléchargement, et gardez une copie locale de la version précise que vous analysez. Faites aussi attention aux données manquantes. ### Pré-requis Traitement de suites chronologiques Quelques références: - [Introduction à l’Étude des Séries Temporelles](https://perso.math.univ-toulouse.fr/jydauxoi/files/2017/04/poly_eleves.pdf) J-Y. Dauxois 2016-2017 - [ARIMA modelling in R](https://otexts.com/fpp2/arima-r.html) - [Séries temporelles – Modèles ARIMA.](https://didierdelignieresblog.files.wordpress.com/2016/03/arimacomplet.pdf) Didier Delignières Séminaire EA "Sport – Performance – Santé" Mars 2000 - [Introduction à la manipulation de série temporelle avec R MAP-STA2 : Séries chronologiques](https://www.imo.universite-paris-saclay.fr/~goude/Materials/time_series/cours1_R_serie_temp.pdf) Yannig Goude yannig.goude@edf.fr 2019-2020 - [Séries temporelles, avec R](http://avram.perso.univ-pau.fr/proc/geo3.pdf) Florin Avram (https://github.com/Peymankor/Data-Science_Portfolio/blob/master/Time%20Series%20Analysis-Historical%20Co2/medium_post.Rmd) ### Pré-traitements sur les données Extrait des métadonnées dans le header du fichier csv téléchargé. The data file below contains 10 columns. - Columns 1-4 give the dates in several redundant formats. - Column 5 below gives monthly Mauna Loa CO2 concentrations in micro-mol CO2 per mole (ppm), reported on the 2008A SIO manometric mole fraction scale. This is thestandard 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 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 is a smoothed version of the data generated from a stiff cubic spline function plus 4-harmonic functions with linear gain. - Column 8 is the same smoothed version with the seasonal cycle removed. - Column 9 is identical to Column 5 except that the missing values from Column 5 have been filled with values from Column 7. - Column 10 is identical to Column 6 except missing values have been filled with values from Column 8. Missing values are denoted by -99.99 CO2 concentrations are measured on the '08A' calibration scale **Chargement des librairies R, du fichier de données, renommage des colonnes, premières statistiques** ```{r, message=FALSE, warning=FALSE} setwd("C:/Users/hraynal/EspaceTravailBadet/FORMATION_PERSO/2020-Reproductibilite/mooc-rr/module3/exo3") library(tidyverse) library(forecast) library(lubridate) library(car) library(scales) library(patchwork) library(kableExtra) dataCO2 <- read.csv("monthly_in_situ_co2_mlo.csv", sep="," ,skip = 57) colnames(dataCO2) <- c("Year", "Month","Date1", "Date2", "ObsCO2", "SeasAdjCO2","SplineAdjCO2", "SplineAdjCO2Trend", "ObsCO2Comp", "SeasAdjCO2Comp") summary(dataCO2) dataCO2$Date <- ymd(paste0(dataCO2$Year, " ", dataCO2$Month, " ", "15")) ``` **Traitement des valeurs manquantes notées -99.99** Il s'avère que dans la série des valeurs observées complétée par les valeurs interpolées, il reste des observations avec des valeurs manquantes (-99.99). On supprime ces observations. ```{r, message=FALSE, warning=FALSE } dataCO2 <- dataCO2[dataCO2$ObsCO2Comp != "-99.99", ] ``` **Création d'une variable date au format YYYY MM DD** ```{r , message=FALSE, warning=FALSE} dataCO2$Date <- ymd(paste0(dataCO2$Year, "-", dataCO2$Month, "-", "15")) ``` ### Représentations graphiques des résultats ```{r, message=FALSE, warning=FALSE } ggplot(dataCO2,aes(Date, dataCO2$ObsCO2Comp)) + geom_line(color='orange') + xlab("Year, Month") + scale_x_date(date_labels = "%Y-%m", date_breaks = "5 year") + theme(axis.text.x = element_text(face = "bold", color = "#993333", size = 12, angle = 45, hjust = 1)) + ylab("CO2 Concentration (ppm)") + scale_y_continuous() + theme(axis.text.y = element_text(face = "bold", color = "#993333", size = 10, hjust = 1),axis.title.y = element_text(size = 10)) + ggtitle("Graphique 1: Evolution au cours du temps de la teneur en CO2") ``` ```{r, message=FALSE, warning=FALSE } dataCO2_by_year <- dataCO2 %>% group_by("Year") ggplot(dataCO2_by_year, aes(dataCO2_by_year$Month,dataCO2_by_year$ObsCO2Comp )) + geom_line(aes( group = dataCO2_by_year$Year , colour=dataCO2_by_year$Year)) + xlab("Month")+ ylab("CO2 Concentration (ppm)") + ggtitle("Graphique 2: Evolution saisonnière de la concentration en CO2, par année") ``` - On déduit du graphique 1 que la série n'est pas stationnaire, elle présente une **tendance** (augmentation du taux de CO2 au cours du temps). - La série montre une **composante saisonnière**, qui semble suivre le cycle annuel, comme en témoigne le graphique 2. En effet les courbes annuelles ont la même forme, tout en étant décalée dans le temps. - On ne voit pas sur ces graphiques de ruptures dans le comportement de la série. - On ne détecte pas d'observations aberrantes. **Question 1: Réalisez un graphique qui vous montrera une oscillation périodique superposée à une évolution systématique plus lente.** ```{r, message=FALSE, warning=FALSE } # Définition en tant que série temporelle Co2_train <- ts(dataCO2$ObsCO2Comp, start = c(1958,3), frequency = 12) T <- time(Co2_train) base <- data.frame(Y=dataCO2$ObsCO2Comp,X1=as.numeric(T)) #essai d'ajustement à un modèle de régression linéaire reg1 <- lm(Y~X1,data=base) tendance1 <-predict(reg1) T <-as.numeric(T) #Calcul des moyennes annuelles de teneur en CO2 # <- cbind( levels(factor(dataCO2$Year)), tapply(dataCO2$ObsCO2Comp, dataCO2$Year, mean)) MeanCO2 <- tapply(dataCO2$ObsCO2Comp, dataCO2$Year, mean) tmp <- ymd(paste0(unique(dataCO2$Year), "-06-15")) MeanCO2Year <- data.frame(tmp , as.numeric(MeanCO2) ) colnames(MeanCO2Year) <- c("Year", "MeanCO2") dataCO2M <- merge( dataCO2, MeanCO2Year, by="Year") ggplot() + geom_line(aes( x=dataCO2$Date, y=dataCO2$ObsCO2Comp), color='orange') + geom_line(aes(x=MeanCO2Year$Year, y=MeanCO2Year$MeanCO2 ), color="blue") + geom_line(aes(x=dataCO2$Date, y=tendance1 ), color="grey") + #geom_line(aes(x=T, y=tendance1 ), color="grey") + xlab("Year, Month") + scale_x_date(date_labels = "%Y-%m", date_breaks = "5 year") + theme(axis.text.x = element_text(face = "bold", color = "#993333", size = 12, angle = 45, hjust = 1)) + ylab("CO2 Concentration (ppm)") + scale_y_continuous() + theme(axis.text.y = element_text(face = "bold", color = "#993333", size = 10, hjust = 1),axis.title.y = element_text(size = 10)) + ggtitle("Graphique 1: Evolution au cours du temps de la teneur en CO2") ``` ### Modélisation de la série temporelle On va chercher à modéliser la série en utilisant une catégorie de modèles qui cherche à déterminer chaque valeur de la série en fonction des valeurs qui la précède (yt = f(yt-1, yt-2, …)). C'est le cas des modèles ARIMA ("AutoRegressive – Integrated – Moving Average"). Cette catégorie de modèles a été popularisée et formalisée par Box et Jenkins (1976). Les processus autorégressifs supposent que chaque point peut être prédit par la somme pondérée d'un ensemble de points précédents, plus un terme aléatoire d'erreur. Le processus d'intégration suppose que chaque point présente une différence constante avec le point précédent. Les processus de moyenne mobile supposent que chaque point est fonction des erreurs entachant les points précédant, plus sa propre erreur. Un modèle ARIMA est étiqueté comme modèle ARIMA (p,d,q), dans lequel: - p est le nombre de termes auto-régressifs - d est le nombre de différences - q est le nombre de moyennes mobiles. On va utiliser la fonction **auto.arima()** qui est un algorithme automatique qui permet de trouver le modèle ARIMA qui estime le mieux la série temporelle. ```{r, message=FALSE, warning=FALSE} Co2_train <- ts(dataCO2$ObsCO2Comp, start = c(1958,3), frequency = 12) Co2_train %>% ggtsdisplay() ``` ```{r, message=FALSE, warning=FALSE} auto.arima(Co2_train) ``` En se basant sur le résultat de l'analyse précédente, on retient le modèle $ARIMA(1,1,1)(2,1,2)[12]$. On peut ensuite vérifier que les résidus ressemblent à un bruit blanc ou non. ```{r, message=FALSE, warning=FALSE} (fit_minaicc <- Arima(Co2_train, order=c(1,1,1),seasonal=list(order=c(2,1,2),period=12), lambda = "auto" )) checkresiduals(fit_minaicc, lag=36) fit_minaicc$aicc ``` Les graphiques précédents montre que le résidu ressemble suffisamment au bruit blanc, que la valeur p est élevée et que le modèle a passé le test de la Ljong-Box. ```{r, message=FALSE, warning=FALSE} autoplot(forecast(fit_minaicc, h=200)) ```