Collecter et cartographier les données du bilan carbone d’un congrès

Cas des Rencontres R’24

Chloé FRIGUET & Francois HUSSON

Introduction

Etablir le bilan carbone d’un événement scientifique : démarche globale éco-responsable

  • quantifier les émissions de gaz à effet de serre (notamment de CO2) ainsi que d’autres paramètres comme la production de déchets ou la consommation alimentaire.
  • charte SFdS, charte UBS, condition pour subventions, etc
  • labo1.5

Contributions :

  • une application R-shiny pour recueillir les informations auprès des participant-e-s
  • des dataviz pour représenter les résultats obtenus

Le questionnaire

Construction d’un questionnaire avec R-shiny

Des solutions existent :

Quetzio shinysurvey

Mais peu de flexibilité pour des champs de saisie personnalisés :

  • Développement d’une application R-shiny ad-hoc pour collecter les données (shinydashboard)
  • Mise à disposition du questionnaire sur le serveur shinyapp.io
  • Recueil des données via une connexion googledrive

Structure du questionnaire et champs de saisie (1)

  • Profil participant-e : type d’employeur, expérience en R, âge, genre (selectInput, numericInput)

Structure du questionnaire et champs de saisie (2)

  • Profil participant-e : type d’employeur, expérience en R, âge, genre (selectInput, numericInput)
  • Habitudes : alimentaires (DT::dataTableOutput + DT::renderDataTable avec callback=JS()), trajet domicile-travail

Structure du questionnaire et champs de saisie (2)

  • Profil participant-e : type d’employeur, expérience en R, âge, genre (selectInput, numericInput)
  • Habitudes : alimentaires (DT::dataTableOutput + DT::renderDataTable avec callback=JS()), trajet domicile-travail (numericInput, sliderInput)

Structure du questionnaire et champs de saisie (3)

  • Profil participant-e : type d’employeur, expérience en R, âge, genre (selectInput, numericInput)
  • Habitudes : alimentaires (DT::dataTableOutput + DT::renderDataTable avec callback=JS()), trajet domicile-travail (numericInput, sliderInput)
  • Trajets pour venir aux RR24: choix et visualisation (textInput+renderUI+UIoutput, selectInput, entrées conditionnelles, carte leafletOutput)

Contrôle de saisie (1)

  • Bouton pour passer d’une page à l’autre et bouton de validation du questionnaire : bloqués + message si incohérence

Contrôle de saisie (2)

  • Bouton pour passer d’une page à l’autre et bouton de validation du questionnaire : bloqués + message si incohérence
  • Titres dynamiques

Contrôle de saisie (3)

  • Bouton pour passer d’une page à l’autre et bouton de validation du questionnaire : bloqués + message si incohérence
  • Titres dynamiques
  • Choix des villes (départ, étape, arrivée) du trajet: Liste des villes avec affichage en cours de saisie, tri par population décroissante

Contrôle de saisie (4)

  • Visualisation du trajet: villes de départ et étape + moyen de transport

  • geonames::GNsearch: latitude et longitude d’une ville en France et à l’étranger

Analyse des résultats

Bilan CO2 par participant

Source : ADEME

Bilan CO2 par participant

Source : ADEME

diagramme circulaire

Repas (5) Trajets Visio Total
quotidien 10.61 3.38 0.96/2.35 15.3
congrès 3.62 21.37 0 24.99

Moyenne des émissions de CO2 par participant

Remarque : une donnée aberrante supprimée : trajet = 8734 kg CO2 e !!!

Villes d’origine des 91 participants

  • carte leaflet
  • fonctions addProviderTiles, addCircleMarkers
  • utilisation de latitude et longitude des villes ainsi que de l’effectif
map <- leaflet() %>% addProviderTiles("OpenStreetMap.Mapnik") %>%  
  addCircleMarkers(data = tab_villes, lng = ~lng, lat = ~lat, radius = ~Freq, 
                   fillOpacity = 1,opacity=1) %>%
  addCircleMarkers(lng = vannes$lng, lat = vannes$lat, radius=2, 
                   fillOpacity = 1,opacity=1,col="red") 

Bilan du CO2 moyen par ville d’origine

  • carte leaflet
  • fonctions addProviderTiles, addCircleMarkers
  • utilisation de latitude et longitude des villes ainsi que de l’effectif
  • coloration des points en fonction du bilan CO2 moyen des habitants d’une ville
pal2 <- colorNumeric(palette=c("green","lightgreen","orange","red", "darkred","black"), 
                     domain = c(0,sqrt(max(dt$meanco2))))
map <- leaflet() %>% addProviderTiles("OpenStreetMap.Mapnik") %>%  
        addCircleMarkers(data = dt, lng = ~lng, lat = ~lat, radius = ~Freq, 
                   color=~pal2(sqrt(meanco2)),fillOpacity = 1,opacity=1) %>%  
        addLegend(position = "topright", pal = pal2, values = sqrt(legend_values),
            labFormat = function(type, cuts, p) { 
              return(as.character(legend_values))
            }, opacity = 1, title = "kg CO2")

Bilan du CO2/km moyen selon la ville d’origine

  • carte leaflet
  • fonctions addProviderTiles, addCircleMarkers
  • utilisation de latitude et longitude des villes ainsi que de l’effectif
  • coloration des points en fonction du bilan CO2/km moyen des habitants d’une ville

Analyse de l’enquête par ACM

  • fonction MCA de FactoMineR
  • var actives : alimentation, trajet quotidien, trajet congrès; illustratives : age, genre

library(FactoMineR)               
res.MCA<-MCA(dta,quali.sup=4:5)

ou

library(Factoshiny)
Factoshiny(dta)

Classification des 91 participants

res.HCPC<-HCPC(res.MCA)     ## Factoshiny(dta)

Caratérisation des classes

  • fonction HCPC de FactoMineR
  • caractérisation des classes par fonction catdes
$`Classe 1 (Effectif = 17)`
                          Cla/Mod  Mod/Cla   Global      p.value    v.test
traj=traj1              68.421053 76.47059 20.87912 2.551566e-08  5.569715
alim=alim1              63.157895 70.58824 20.87912 6.633352e-07  4.971802
trajquotidien=trajQuot1 38.461538 88.23529 42.85714 3.251304e-05  4.155110
ageQ=31-39              31.428571 64.70588 38.46154 1.840147e-02  2.357439
ageQ=- de 30             6.451613 11.76471 34.06593 3.027185e-02 -2.166515

$`Classe 2 (Effectif = 12)`
                         Cla/Mod  Mod/Cla   Global      p.value   v.test
trajquotidien=trajQuot3 75.00000 75.00000 13.18681 5.643690e-08 5.429738
traj=traj2              55.55556 83.33333 19.78022 3.793299e-07 5.079048
ageQ=- de 30            29.03226 75.00000 34.06593 2.717341e-03 2.998026
alim=alim3              33.33333 50.00000 19.78022 1.336824e-02 2.473806

$`Classe 3 (Effectif = 17)`
            Cla/Mod  Mod/Cla   Global      p.value   v.test
alim=alim2 84.21053 94.11765 20.87912 6.101291e-14 7.505889
traj=traj3 38.88889 41.17647 19.78022 2.587274e-02 2.228117

$`Classe 4 (Effectif = 12)`
                         Cla/Mod   Mod/Cla   Global      p.value  v.test
trajquotidien=trajQuot2 52.17391 100.00000 25.27473 4.285478e-09 5.87278
traj=traj3              38.88889  58.33333 19.78022 1.836896e-03 3.11541

$`Classe 5 (Effectif = 18)`
            Cla/Mod  Mod/Cla   Global      p.value   v.test
traj=traj4 94.44444 94.44444 19.78022 2.785726e-16 8.182259

$`Classe 6 (Effectif = 15)`
                         Cla/Mod  Mod/Cla   Global      p.value   v.test
traj=traj5              72.22222 86.66667 19.78022 4.188090e-10 6.246851
trajquotidien=trajQuot4 64.70588 73.33333 18.68132 2.745612e-07 5.140121
alim=alim5              38.88889 46.66667 19.78022 1.072897e-02 2.551404
alim=alim4              35.29412 40.00000 18.68132 3.740771e-02 2.081286



res.HCPC$desc.var

Tracé d’un trajet sur une carte

  • fonction addPolylines
  • épaisseur des traits proprotionnelle au nb d’itinéraires identiques
  • très bien … pour les avions
  avion <- aggregate(Effectif ~ ., data = avion, FUN = sum)
  for (i in 1:nrow(avion)){
    map <-addPolylines(map, lng=c(avion$lng.d[i],avion$lng.a[i]),
            lat=c(avion$lat.d[i],avion$lat.a[i]), weight=avion$Effectif)
  }

Trouver un itinéraire et la distance associée

  • en avion : geosphere::distHaversine calcule les distances à vol d’oiseau
    (⮕ utile pour les avions seulement !)
distHaversine(traj[,c("lng.d","lat.d")],traj[,c("lng.a","lat.a")])/1000
  • en voiture, vélo, piéton : osrm::osrmRoute retourne un objet sf avec itinéraire vélo, piéton ou voiture et distance réelle
osrmRoute(src = traj[i,c("lng.d","lat.d")],dst = traj[i,c("lng.a","lat.a")], 
          osrm.profile="car")
  • en train : réseau inexistant ou avec les horaires de tous les trains ⮕ trop lourd
    Récupérer les données depuis l’API : https://trainmap.ntag.fr/ :
url <- paste0("https://trainmap.ntag.fr/api/route?dep=",lng.d,",",lat.d,
              "&arr=",lng.a,",",lat.a) 
tra <- content(GET(url),"text") 
routes <- st_cast(st_boundary(st_make_valid(st_read(tra))),"LINESTRING") 

Paris et Bordeaux posent pb ⮕ modifier lat et long pour mettre le centre de Paris

Construire un réseau à partir d’itinéraires

  • Création d’un réseau pour voiture, un autre pour réseau ferré, un autre pour vélo
  • Comptage du nombre de personnes parcourant une même partie de trajet
  • Superposition des trajets et bouts de trajets
  • stplanr::overline
  tab_routes <- NULL
  for (i in 1:nrow(traj_car)){ 
    tab_routes <- rbind(tab_routes,
                        osrmRoute(src = traj_car[i,c("lng.d","lat.d")],
                                  dst = traj_car[i,c("lng.a","lat.a")],
                                  osrm.profile="car"))
  }
  tab_routes$total = rep(1,nrow(tab_routes))
  reseau_car <- overline(tab_routes, attrib = "total")

Carte des déplacements par la route

  • chaque route du réseau est convertie en coordonnées puis tracée comme une suite de petites lignes droites
for (i in 1:nrow(reseau_car)) {
  route <- reseau_car[i, ]
  coords <- st_coordinates(route$geometry)
  map <-addPolylines(map, lng=coords[,1], lat=coords[,2], 
                     weight=sqrt(route$total), color="red")
}

Carte des déplacements du congrès Rencontres R

  • Superposer tous les réseaux (voiture, vélo, train)
  • pour les trains … qq petits pb à régler

Conclusion - perspectives

  • R permet :

    • la construction de questionnaire avec shiny
    • le traitement du questionnaire
    • la visualisation par des cartes … même si parfois ce n’est pas pas immédiat
  • L’empreinte carbone est une mesure relativement facile à obtenir, il faudrait évaluer d’autres indicateurs (gestion ressources, provenance locale, plastique, etc.)

  • Quantifier/mesurer est indispensable - visualiser est nécessaire pour faire passer les idées et faire prendre conscience
    ⮕ rôle important à jouer en tant que data scientists

Merci pour votre participation au questionnaire et merci pour votre attention