Agriculture de précision

en langage R

L'essentiel de cette page

Ce guide "Agriculture de précision en langage R" présente les étapes essentielles pour l'utilisation de R dans le domaine de l'agriculture de précision. Il aborde les points suivants :

0. Préparation des données : importation de données captées par drone et de données satellitaires via Pix4Dfields.

0- Préparer les données - ici avec Pix4Dfiels

Pas de traitement de données sans données.

Ici l'on présentera des données captées par Drone ainsi que des données satellitaires importées grâce au logiciel pix4Dfields.


Cliquer sur ce lien pour voir comment exporter vos données pix4Dfields vers R pour faire le traitement du présent tuto.

1- Charger les données de l'orthomozaïque et les données satellitaires dans R

Nous allons ouvrir les données satellitaires dans un objet raster r1 et les données orthomozaïques du drone dans un objet raster r0_ortho.

library(terra)

# Données Satellite - basse résolution

r0 <- terra::rast(file.choose()) # 2023-05-15, Délimitation 2, NDVI.data.tif

r1 <- rectify(r0) # Faire une rotation du raster si message d'alterne rectify à l'ouverture

# Attention, Pix4Dfields fournit bcp d'images, assurez-vous d'avoir chargé l'image à plusieurs bandes en faisant names(r1)

# Données Drone - très grande résolution

r0_ortho <- terra::rast(file.choose()) # Orthomosaïque.data.tif

# AFFICHAGE EN COULEURS NATURELLES

names(r0)

terra::plotRGB(r0_ortho,1,2,3) # 1, 2, 3 ordre des couches rgb

terra::plotRGB(r1*1810,3,2,1) # ne marche pas car les couches ne sont pas codés de 0 à 255, il faut donc multiplier par 255/max(value)

Optionnellement, je peux aussi forcer le raster à raisonner en longitude-latitude pour pouvoir ajouter des points de repères où le placer sur une carte.

# Définir la nouvelle projection

new_crs <- "+proj=longlat +datum=WGS84"

r1_long_lat<- project(r1, new_crs) # terra

Pour se simplifier la vie, on ne va pas le faire ici.

Remarque importante : la fonction res() permet d'avoir la dimension en mètres des pixels. Cela ne sert à rien d'avoir une résolution au-delà de 5 mètres si l'on souhaite faire un traitement personnalisé avec un gros tracteur.

res(r1) #  0.01679497 0.01679497 Mes pixels ont une précision de 1,6 cm. Ca va loin...

5/res(r0_ortho) # Cela donne le facteur de réduction que je peux appliquer à mon raster (entre 200 et 300 ici) 

On se retrouve maintenant avec un raster satellitaire de basse résolution et une orthomozaïque drone trop lourd à manipuler. On va donc compresser le dernier et augmenter la résolution du premier.

dim(r1) # 64 79 11 - mesures à 11 lambdas, image de 64 sur 79 pixels.

dim(r0_ortho) #  19911 25257     4 # Seulement 3 mesures (rgb + masque de la zone binaire) : on peut réduire facilement d'un facteur 200

# Aggreger le raster drone

facteur <- 200 # A ajuster si on ne veut pas trop perdre

r1_ortho <- aggregate(r0_ortho, facteur, fun = median) # Ca va être long, car il faut faire la médiane sur chaque carré de 200 pixels sur 200

dim(r1_ortho)

# Resample le raster satellitaire à la résolution du raster drone

r2 <- resample(r1, r1_ortho, method = "bilinear")


# Affichage

layout(matrix(1:2,2,1)) ; terra::plotRGB(r1_ortho,1,2,3) ; terra::plotRGB(r2*1818,3,2,1) # 1818 car les données satellitaires ont une échelle basse (255/max)

Convertissons maintenant toutes les donnée des deux rasters en un tableau data.frame. Il sera possible sur ce tableau de faire des ACP et autres calculs, mais c'est peut-être plus pertinent de faire directement un calculs des indices.

# Mise au format tableau et fusion

df1 <- as.data.frame(r2,xy=TRUE)

df2 <- as.data.frame(r1_ortho,xy=TRUE)

# Fusionner les dataframes en utilisant les colonnes x et y comme clés de fusion

df <- merge(df1, df2, by = c("x", "y"))

df <- na.omit(df) # suppression des lignes sans données

colnames(df)

df[-ncol(df)]-> df # étape optionnelle : suppression de la dernière colonne (inutile : masque de la zone)

colnames(df)[c(14,15,16)] <- c("Red_ortho","Green_ortho","Blue_ortho")

2- Calculer les indices nécessaires à établir un diagnostic agronomique

Il existe de nombreux indices en télédétections, certains sont plus courants, tels de VARI (Couverture végétal), le TGI (Charge chlorophyllienne) et NDWI (stress hydrique). Leurs formules peuvent hélas varier pour certains d'une publication à l'autre :

Voici quelques formules qui vont nous permettre de calculer rapidement ces indices à partir de rasters.

Calcul du TGI : l'aire de ce triangle (source)

Si vos images Pix4Dfields n'ont pas des noms correspondant à ceux indiqués, voici une légende des 11 bandes présentes dans l'ordre : 

"Blue"      "Green"     "Red"       "Red edge"  "Red edge"  "Red edge"  "NIR"       "NarrowNIR" "SWIR"      "SWIR"      "Alpha"  

# VARI

vari<- function(r,g,b) {

  if (is(r)[1] == "SpatRaster") {

vari <- clamp(((g - r) / (g+ r - b)),-1,1)# Version pix4Dfields normalisée entre -1 et 1

              } else {

        vari <- (g - r) / (g+ r - b)  

  }        

return(vari)

}

# TGI

tgi <- function(r,g,b) {

rr <- as.data.frame(r) ; gg <- as.data.frame(g) ; bb <- as.data.frame(b)

# Normaliser le pixel pour normaliser le TGI

tgi <- (g-0.39*r-0.61*b)/max(apply(cbind(rr,gg,bb),2,max))

#bbb <- -0.5*(190*(r-v) - 120*(r-b))#/max(c(r,v,b))

#print(cor.test(as.data.frame(tgi)[,1],as.data.frame(bbb)[,1]))

#plot(as.data.frame(tgi)[,1],as.data.frame(bbb)[,1])

return(tgi)

}

# NDWI

ndwi <- function(g, nir) {

ndwi<- (g - nir)/(g + nir)

return(ndwi)

}

# On notera que certains suggèrent de faire un NDWI/NDMI avec cette formule  (NIR - SWIR) / (NIR + SWIR)  

On peut ainsi calculer ces indices directement à partir des raster, mais il est plus simple de les appliquer sur data.frame (encadré suivant).

r2_vari <- vari(r2[["Red"]],r2[["Green"]],r2[["Blue"]])

r1_ortho_vari <- vari(r1_ortho[[1]],r1_ortho[[2]],r1_ortho[[3]])

# Affichage

layout(matrix(1:2,2,1)) ;  plot(r1_ortho_vari,main="Drone") ; plot(r2_vari,main="Satellite")

Fait intrigant qui mériterait qu'on s'y penche, le VARI de l'image drone (en haut) ne donne pas le même VARI pour l'image satellite (en bas). On comprend que ces images sont bien différentes, mais laquelle garder ?

Le plus simple est toujours de travailler avec les données en tableurs.

# Reprenons la data.frame df ci-dessus.

colnames(df)

col_vari <- vari(df$Red,df$Green,df$Blue)

col_vari2 <- vari(df$Red_ortho,df$Green_ortho,df$Blue_ortho)

col_tgi <- tgi(df$Red,df$Green,df$Blue)

col_tgi2 <- tgi(df$Red_ortho,df$Green_ortho,df$Blue_ortho)

col_ndwi <- ndwi(df$Green,df$NIR)

col_ndwi2 <- ndwi(df$Green_ortho,df$NIR*255/max(df$NIR))

df_indices <- data.frame(col_vari,col_vari2,col_tgi,col_tgi2,col_ndwi,col_ndwi2)

Remarque importante : il existe d'autres indices peut être nettement plus pertinents, pour en citer certains :

Normalized Difference Vegetation Index (NDVI) : Utilisé pour estimer la biomasse, l'indice foliaire (LAI) et l'activité photosynthétique dans les prairies mixtes et les chaparrals en Californie du Sud, avec une taille de pixel optimale de 6 m ou moins pour des études fonctionnelles (Rahman et al., 2003)​​. On peut aussi inclure le NDVI2 certainement plus pertinent.

Renormalized Difference Vegetation Index (RDVI) : Comparaison avec d'autres indices pour l'estimation de l'indice foliaire (LAI) dans des écosystèmes de prairies mixtes, montrant une légère amélioration par rapport aux autres indices (He et al., 2006)​​.

Adjusted Transformed Soil-Adjusted Vegetation Index (ATSAVI) : Utilisé pour améliorer l'estimation du LAI dans les prairies, particulièrement lorsqu'il est combiné avec l'indice d'absorption de cellulose (CAI) pour un nouvel indice (L-ATSAVI), augmentant la capacité d'estimation de l'AGB d'environ 10% (He et al., 2006)​​.

Water Band Index (WBI) : employé comme indicateur de contenu en eau des plantes dans les prairies et les chaparrals, avec des analyses de mise à l'échelle spatiale pour optimiser les procédures d'échantillonnage (Rahman et al., 2003)​​.

Photochemical Reflectance Index (PRI) : Utilisé pour les études de la biomasse, du contenu en eau des plantes et de l'activité photosynthétique (Rahman et al., 2003)​​.

Modified Chlorophyll Absorption Ratio Index 2 (MCARI2) : Performant pour estimer le LAI dans les prairies mixtes (He et al., 2006)​​.

Pure Vegetation Index (PVI) : Un index extrait du VI normal pour minimiser les effets du sol, améliorant ainsi les estimations de l'AGB des prairies (Li et al., 2016)​​.

Cellulose Absorption Index (CAI) : Utilisé en combinaison avec ATSAVI pour améliorer les estimations de LAI en tenant compte de la matière morte au sol (He et al., 2006)​​.

Soil Adjusted Total Vegetation Index (SATVI) : Développé pour estimer la couverture végétale totale, la hauteur et la biomasse dans les prairies arides (Marsett et al., 2006)​​.

3- Combiner les indices pour réaliser un regroupement : identifier les types de zones de la parcelle

3.1- ACP - réduire les indices à quelques composantes - optionnel mais utile si beaucoup d'indices

apply(df_indices,2,function(x){any(is.na(x))}) # Vérifier qu'une donnée manquante ne s'est pas glissée dans le tableau

myacp <- prcomp(na.omit(df_indices),center=T,scale=T)

library(KefiR)  # Pour installer KefiR

pareto(myacp$sdev)

biplt(myacp,labels="",cex=0.2)

library(rgl)

plot3d(myacp$x[,1:3])

pareto() de {KefiR}

Ce Pareto montre que l'on peut réduire les 6 indices à 3-4 composantes

biplt() de {KefiR}

Ce biplot() réalisé avec {KefiR} permet de voir la dispersion des points en nuages et les variables VARI et NDWI qui jouent le plus.

plot3d() de {rgl}

Ce graphique 3D permet de voir les groupes de pixels sur la parcelle : il faut envisager de les identifier (regroupement) et les caractériser.

On peut aussi transformer les résultats de l'ACP pour reproduire une image.

# install.packages("tidyterra")

library(tidyterra)

tablo <- cbind(df[-which(apply(df_indices, 1, function(x) {any(is.na(x))})),1:2],myacp$x[,1:3])

tablo[,3:5] <- apply(tablo[,3:5] ,2,function(x) {(x-min(x))/(max(x)-min(x))*255})

myraster <- as_spatraster(tablo)

terra::plotRGB(myraster*50,1,2,3)

terra::plotRGB(myraster*50,1,1,1) # Que la composante 1

3.2- Faire du regroupement - pour identifier les zones à diagnostiquer

A titre d'exemple, utilisont le CAH pour déterminer le nombre de zones dans la parcelle.

myclust <- hclust(dist(df_indices), method="ward.D2")

#plot(myclust)

inertie <- sort(myclust$height, decreasing = TRUE)

plot(inertie[1:20], type = "s", xlab = "Nombre de classes", ylab = "Inertie",lwd=2);grid()

k <- 3 # Nombre de catégories à paramétrer manuellement selon le graphique

abline(v=k,col="red",lty=3)

points(k,inertie[k],pch=16,cex=2,col="red")

Les 2 grands bons à 3 ou 4 catégories suggèrent que l'on peut avec pertinence travailler sur 3 ou 4 types de zones (l'indication en rouge correspond ici à 3 catégories).

Remarque : il ne faut pas hésiter à centrer-réduire les données avant avec scale()

Les comparaisons des images montre que 4 zones est assez pertinent.

cutree(myclust, k=3) # 3 catégories

raster_catego <- rast(data.frame("x"=df$x,"y"=df$y,"z"=cutree(myclust, k=3)))

x11()

plot(raster_catego) 

On voit ici, les cinq zones identifiées sur la parcelle, mais avec pas mal d'erreur sur les bords.

En mettant en place un mélange de gaussiennes, on va être plus fin pour identifier les zones qui correspondent à la réalité du terrain. 

Le CAH aura permis de fixer que G=4.

library(mclust)

df_indices <- cbind("x"=df$x,"y"=df$y,df_indices)

df_indices <- na.omit(df_indices)

Mclust(df_indices[,-c(1,2)], G = 4) -> my_mclust

summary(my_mclust)

names(my_mclust)

raster_catego <- rast(data.frame("x"=df_indices$x,"y"=df_indices$y,"z"=my_mclust$classification))

plot(raster_catego) 

Une classification (et non un regroupement) va permettre d'essayer de reprédire ces zones uniquement en fonction de leur position x ou y. On va ainsi faire un lissage.

On peut par exemple faire un SVM ou un dbscan. Le SVM est performant et gagnera en finesse avec le paramètre cross.

# Ajuste un modèle SVM en utilisant 

model <- svm(as.factor(my_mclust$classification)~ ., df_indices[,1:2], cross = 10)


# Utilise le modèle pour prédire les valeurs de la variable dépendante pour toutes les observations, sauf la variable dépendante elle-même

mypred <- predict(model, subset(df_indices[,1:2]))

raster_catego <- rast(data.frame("x"=df_indices$x,"y"=df_indices$y,"z"=as.numeric(mypred)))

# Définit les couleurs

my_colors <- c("red", "blue", "green", "yellow")

# Plot le raster avec les couleurs définies

plot(raster_catego, col=my_colors)

On peut recoloriser les zones pour clarifier leur identification.

La technique SVM permet de dégager les zones trop petits, de faire ainsi un lissage.

df_indices_categories <- cbind(df_indices,mypred)

#install.packages("rpart.plot")

#install.packages("rpart")

library(rpart)

# Construire un modèle des catégories 1, 2, 3

# La 4 est sortie car correspondant aux zones de bordures

model<-rpart(mypred~.,data=df_indices_categories[mypred!=4,-c(1:2)] ,control=rpart.control(minsplit = 9,cp=0))

plot(model)

# Simplification du modèle

model_pruned <- prune(model, cp = 0.01)

plot(model_pruned)

library(rpart.plot)

rpart.plot(model_pruned)

On voit ainsi que la catégorie 3 présente un indice NDWI (celui déterminé à partir des données du drone) inférieur à -0.66. Cela implique que cette zone présente un fort stress hydrique qui justifiera qu'on lui donne plus d'eau (ou qu'on change d'autres modalités de culture). Au passage, on notera que les zones considérées en catégorie 3 par cet arbre ne le seront effectivement qu'à 89% (11% seront en réalité de la catégorie 1). On peut toujours affiner un tel arbre en faisant des forêts aléatoires qui permettront de ne conserver que les indices les plus influents avant de recommencer le cycle regroupement(catégorisation) des étapes ci-avant.

Pour séparer la catégorie 1 de la catégorie 2, seul l'indice VARI (celui déterminé par drone) a été retenu. Il permet de décrire la zone 1 comme présentant une faible vigueur de végétation. Sans surprise, la catégorie 2 représente de la végétation plus verte et plus vigoureuse.

Il faudrait donc, en théorie, faire maintenant appel à un.e expert.e pour proposer des traitements différenciés.

Les données compilées en raster peuvent être exportées en tiff, recompilées avec pix4Dfield pour permettre d'automatiser le travail d'un tracteur.

On peut envisager d'importer un raster zonal (importation > indice) dans pix4Dfields pour retraiter les données.

writeRaster(raster_catego, "raster_catego_new1.tif")

Solution peut-être plus simple, l'exporté en shape pour l'ouvrir avec QGIS :

sortie1 <-  raster::raster(raster_catego)

sortie2 <-  raster::rasterToPolygons(sortie1, dissolve=TRUE)

plot(sortie2,col=1:4)

raster::shapefile(sortie2, "votre_shapefile.shp")

raster::shapefile(sortie2, "votre_shapefile.shp",overwrite=TRUE)

On peut aussi directement traiter les données statistiquement et graphiquement sous R


Bilan statistique

colnames(df_indices_categories)

bilan <- aggregate(df_indices_categories[,c(4)],by=list(df_indices_categories$mypred),summary)

bilan2 <- t(bilan[,-1]) ; colnames(bilan2) <- bilan[,1] ; print(round(bilan2[,-4],2)) # Indie VARI (colonne 4)

            1    2    3

Min.    -0.04 0.02 0.00

1st Qu.  0.06 0.13 0.06

Median   0.07 0.15 0.08

Mean     0.07 0.15 0.08

3rd Qu.  0.08 0.17 0.09

Max.     0.13 0.23 0.14

Etudier une variable en fonction des zones

boxplot(df_indices_categories$col_vari~df_indices_categories$mypred,xlab="zones",ylab="VARI")

Etudier deux variables en fonction des zones (voire 3 en plot3D())

plot(df_indices_categories$col_vari,df_indices_categories$col_ndwi2, 

col=df_indices_categories$mypred,cex=0.1,pch=16,xlab="VARI satellite",ylab="NDWI drone") ;  grid()

Analyser l'ensemble des variables pour les zones (ici 3 variables)

layout(matrix(1:3,1,3)) ; library(vioplot)

vioplot(df_indices_categories$col_vari~df_indices_categories$mypred,xlab="zones",ylab="VARI",col="red")

vioplot(df_indices_categories$col_tgi~df_indices_categories$mypred,xlab="zones",ylab="TGI",col="yellow")

vioplot(df_indices_categories$col_ndwi~df_indices_categories$mypred,xlab="zones",ylab="NDWI",col="cyan")


4- Suivre la saisonnalité

Pour construire un graphique qui l'évolution d'un indice en fonction des mois de l'année, il faut procéder en plusieurs étapes :

library(terra)

setwd("G:/Drone/Export/La Forge/NDVI/La Forge") # Mettre l'adresse de son dossier

tif_files <- list.files(pattern = "Délimitation 2.data.tif$", full.names = TRUE) # Ouvre tous les tif terminant par Délimitation 2.data.tif

colnames(tif_files)

Cette image illustre le suivi de l'indice NDWI sur une année  à titre d'exemple. Un autre indice (ou plusieurs) peut s'avérer pertinent.

On peut aussi (recommandé), étudier plusieurs indices sur le même graphique en traçant différentes courbes en couleur (à légender).

# Initialiser des vecteurs pour stocker les mois et les années

dates <- c()

months <- numeric(length(tif_files))

years <- numeric(length(tif_files))

days <- numeric(length(tif_files))


# Pour chaque fichier .tif

for (i in seq_along(tif_files)) {

  # Extraire la date du nom du fichier

  file_name <- basename(tif_files[i])

  date_str <- substr(file_name, 1, 10)

  # Convertir la date en objet Date

  date <- as.Date(date_str)

  # Extraire le mois et l'année de la date

  dates <- c(dates,as.character(format(date, "%Y-%m-%d")))

  days[i] <- as.numeric(format(date, "%d"))

  months[i] <- as.numeric(format(date, "%m"))

  years[i] <- as.numeric(format(date, "%Y"))

}


# Nettoyer la liste de TIFF du dossier pour ne garder que ceux de l'année en cours

dates <- strptime(dates,format="%Y-%m-%d")

indices <- which(as.Date(dates) >= as.Date("2022-05-31")) # Ici on ne garde que les TIFF ayant dépassé mai 2022

tif_files <- tif_files[indices]

# Initier les listes des valeurs extraites de chaque TIFF

dates <- c()

months <- numeric(length(tif_files))

years <- numeric(length(tif_files))

days <- numeric(length(tif_files))

indice <- numeric(length(tif_files))


# Pour chaque tif de l'année en cours

for (i in seq_along(tif_files)) {

  # Ouvrir le fichier .tif en tant qu'objet raster

  r0 <- terra::rast(tif_files[i])

  r1 <- rectify(r0)

  # Calcule de l'indice du TIFF (ici NDWI)

  indice.temp <- ndwi(r1[["Green"]],r1[["NIR"]]) 

  # Extraire la date du nom du fichier

  file_name <- basename(tif_files[i])

  date_str <- substr(file_name, 1, 10)

  # Convertir la date en objet Date

  date <- as.Date(date_str) 

  # Extraire le mois et l'année de la date

  dates <- c(dates,as.character(format(date, "%Y-%m-%d")))

  days[i] <- as.numeric(format(date, "%d"))

  months[i] <- as.numeric(format(date, "%m"))

  years[i] <- as.numeric(format(date, "%Y"))

  # Calcule de l'indice médian de l'image

  indice[i] <- median(as.data.frame(indice.temp[[1]])[,1],na.rm=T)

}

dates <- strptime(dates,format="%Y-%m-%d")

plot(dates,indice,type="o",axes=F,lwd=2) ; grid()

# Abscisses exprimant dans ses graduations uniquement le nom des mois

axis.POSIXct(1, at=seq(from=strptime("01/06/2022","%d/%m/%Y" ), to=strptime("31/05/2023","%d/%m/%Y" ), by="month"), format="%b", las=2) # force indiquant la date de chaque jour

# Ordonnées

axis(2,seq(from = -1, to=1,by=0.1))

5- Suivre l'évolution du "climat" (il faudrait en théorie 30 ans)

Suivre une éventuelle évolution du climat. Pour l'instant, les bases de données ne couvrent qu'une dizaine d'année (2023), mais cela va progresser.

Il faut charger tous les TIFF du mois de l'analyse sur un maximum d'année.

L'étude du champ ici montre une hausse de l'indice VARI depuis 2017 (en cinq ans), et une légère baisse de l'indice NDWI. Le graphique ici n'affiche que l'évolution du VARI. Rien n'exclue d'étudier l'évolution de plusieurs indices.

library(terra)

setwd("G:/Mon Drive/IUT/statistiques/SAE_AGRO/Drone/Export/La Forge/NDVI/La Forge")

tif_files <- list.files(pattern = "Délimitation 2.data.tif$", full.names = TRUE)


# Initialiser des vecteurs pour stocker les mois et les années

months <- numeric(length(tif_files))

years <- numeric(length(tif_files))

days <- numeric(length(tif_files))

indice <- numeric(length(tif_files))

dates <- c()

# Pour chaque fichier .tif

for (i in seq_along(tif_files)) {

  # Ouvrir le fichier .tif en tant qu'objet raster

  r0 <- terra::rast(tif_files[i])

  r1 <- rectify(r0)

  indice.temp <- vari(r1[["Red"]],r1[["Green"]],r1[["Blue"]])

  #indice.temp <- ndwi(r1[["Green"]],r1[["NIR"]])

  # Extraire la date du nom du fichier

  file_name <- basename(tif_files[i])

  date_str <- substr(file_name, 1, 10)

  # Convertir la date en objet Date

  date <- as.Date(date_str)

  # Extraire le mois et l'année de la date

  dates <- c(dates,as.character(format(date, "%Y-%m-%d")))

  days[i] <- as.numeric(format(date, "%d"))

  months[i] <- as.numeric(format(date, "%m"))

  years[i] <- as.numeric(format(date, "%Y"))

  indice[i] <- median(as.data.frame(indice.temp)[,1],na.rm=T)

}


Tracer le graphique et analyser la régression

dates <- strptime(dates,format="%Y-%m-%d") 

synth <- data.frame("dates"=as.numeric(dates),"indice"=indice)

plot(dates,indice,axes=F,data=synth)

reg <- lm(indice~as.numeric(dates))

summary(reg)

abline(reg,col="red",lwd=3)

axis.POSIXct(1, at=seq(from=strptime(dates[1],"%Y-%m-%d" ), to=strptime(dates[length(dates)],"%Y-%m-%d" ), by="year"), format="%Y", las=2) # force indiquant la date de chaque jour

# Ordonnées

axis(2,seq(0,1,by=0.1))


Call:

lm(formula = indice ~ as.numeric(dates))


Residuals:

     Min       1Q   Median       3Q      Max 

-0.26641 -0.11099 -0.04687  0.11155  0.45676 


Coefficients:

                    Estimate Std. Error t value Pr(>|t|)    

(Intercept)       -2.562e+00  7.002e-01  -3.660 0.000599 ***

as.numeric(dates)  1.565e-09  4.312e-10   3.629 0.000659 ***

---

Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1


Residual standard error: 0.1601 on 51 degrees of freedom

Multiple R-squared:  0.2052,    Adjusted R-squared:  0.1896 

F-statistic: 13.17 on 1 and 51 DF,  p-value: 0.0006588



Permettons nous une prédiction. Comment sera l'indice VARI en 2030 ?

Actuellement, lors de cet étude, il est de 0.21 (mai 2023), mais il devrait passer à 0.42 en mai 2030.

Si j'applique le même raisonnement en changeant d'indice, je trouve une évolution moins significative du NDWI qui devrait le faire passer de -0.62 à -0.67. Cela permet de diagnostiquer que, sans surprise, le stress hydrique semble à la hausse, mais que, pour l'instant, la végétation profite de la hausse des températures* (*Attention diagnostic sur seulement cinq ans).

median(df_indices_categories$col_vari) # Mai 2023, mois de l'étude

Prédire sa valeur pour une date.

date_to_predict <- "2030-05-30"

predict(reg,data.frame("dates"=as.numeric(strptime(date_to_predict,format="%Y-%m-%d"))))