ENT101: Échantillonnage du campus UdS

Guide complet pour le traitement de données entomologiques avec R

Matériel de cours pour ENT101 - Travaux pratiques en Entomologie (Université de Sherbrooke, été 2025) : manipulation de données spatiales, cartographie, intégration de données climatiques (NASA POWER) et visualisation de données entomologiques avec R.
R
entomologie
données spatiales
ENT101
Author

Allen Bush-Beaupré

Published

July 13, 2025

Keywords

Allen Bush-Beaupré, ecological statistics, agricultural entomology, integrated pest management, Bayesian statistics, statistical consulting, GLMM, Université de Sherbrooke, CREUS, Bishop’s University

UdeS Logo

1 Introduction

TipObjectifs d’apprentissage

À la fin de ce tutoriel, vous serez capable de :

  • Organiser un projet R reproductible pour l’analyse de données entomologiques
  • Manipuler et visualiser des données spatiales avec le package sf
  • Créer des cartes professionnelles avec ggplot2 et ggspatial
  • Intégrer des données climatiques via l’API NASA POWER
  • Nettoyer et transformer des données biologiques
  • Créer des visualisations avancées pour la communication scientifique

Ce tutoriel vous guidera à travers une analyse complète de données entomologiques incluant :

  • Manipulation de données spatiales : pièges et zones d’échantillonnage
  • Visualisation cartographique : cartes de fond contextuelles
  • Intégration de données climatiques : API NASA POWER pour les conditions météorologiques
  • Analyse temporelle : traitement des dates et fuseaux horaires
  • Visualisations avancées : graphiques publication-ready
  • Workflow reproductible : bonnes pratiques de recherche
NotePrérequis
  • Connaissance de base de R et RStudio
  • Installation de R (≥ 4.0) et RStudio

1.1 Vue d’ensemble du workflow

flowchart TD
    A[Organisation du projet R] --> B[Chargement des données spatiales]
    B --> C[Exploration et classification des sites]
    C --> D[Création de cartes contextuelles]
    D --> E[Extraction des coordonnées]
    E --> F[Intégration des données climatiques]
    F --> G[Traitement des données biologiques]
    G --> H[Nettoyage et transformation]
    H --> I[Visualisations avancées]
    I --> J[Tableaux et export]
    J --> K[Rapport final]
Figure 1: Workflow général du tutoriel d’analyse spatio-temporelle en entomologie.

2 Configuration de l’environnement et outils

2.1 Chargement des librairies

NoteConfiguration de l’environnement R

Avant de commencer l’analyse, nous devons configurer notre environnement R avec toutes les librairies nécessaires. Cette section installe et charge tous les packages requis pour le tutoriel.

2.1.1 Installation des packages (si nécessaire)

# Installation des packages nécessaires (exécuter seulement si besoin)
packages_needed <- c(
  "tidyverse", "nasapower", "readxl", "sf", 
  "ggspatial", "patchwork", "janitor", "lubridate",
  "tinytable", "here", "cowplot"
)

# Vérifier et installer les packages manquants
packages_to_install <- packages_needed[!(packages_needed %in% installed.packages()[,"Package"])]
if(length(packages_to_install)) install.packages(packages_to_install)

2.1.2 Chargement des librairies principales

# ========================================
# PACKAGES PRINCIPAUX POUR L'ANALYSE
# ========================================

# Manipulation et visualisation de données
library(tidyverse)    # Collection complète : dplyr, ggplot2, tidyr, etc.
library(lubridate)    # Manipulation des dates et heures

# Données spatiales et cartographie
library(sf)           # Simple Features pour les données spatiales
library(ggspatial)    # Extensions cartographiques pour ggplot2

# Lecture et écriture de données
library(readxl)       # Import de fichiers Excel
library(janitor)      # Nettoyage automatique des données

2.1.3 Chargement des librairies spécialisées

# ========================================
# PACKAGES SPÉCIALISÉS
# ========================================

# Données climatiques
library(nasapower)    # Accès aux données météorologiques NASA POWER

# Visualisation avancée
library(patchwork)    # Combinaison de graphiques
library(cowplot)      # Manipulation avancée de graphiques

# Tableaux et export
library(tinytable)    # Tableaux professionnels

# Gestion des chemins de fichiers
library(here)         # Chemins relatifs reproductibles

2.1.4 Vérification de l’installation

[1] "Statut des packages :"
            Package Loaded Version
tidyverse tidyverse   TRUE   2.0.0
sf               sf   TRUE   1.1.2
ggspatial ggspatial   TRUE  1.1.10
nasapower nasapower   TRUE   4.3.0
readxl       readxl   TRUE   1.5.0
janitor     janitor   TRUE   2.2.1
patchwork patchwork   TRUE   1.3.2
lubridate lubridate   TRUE   1.9.5
tinytable tinytable   TRUE  0.17.0
here           here   TRUE   1.0.2
cowplot     cowplot   TRUE   1.2.0
TipRôle de chaque package
  • tidyverse : Écosystème complet pour la manipulation et visualisation de données
  • sf : Standard moderne pour les données spatiales (remplace sp)
  • ggspatial : Extensions cartographiques pour créer des cartes avec ggplot2
  • nasapower : Accès direct aux données météorologiques satellites NASA
  • patchwork : Combinaison élégante de multiples graphiques
  • janitor : Nettoyage automatique des noms de colonnes et données
  • tinytable : Création de tableaux professionnels pour publication

2.2 Introduction au tidyverse

Le tidyverse est une collection cohérente de packages R conçus pour la science des données. Il révolutionne la façon dont nous travaillons avec les données en R en offrant une syntaxe claire, lisible et cohérente.

2.2.1 Principes fondamentaux du tidyverse

Le tidyverse repose sur la philosophie des “tidy data” (données bien organisées) :

  1. Chaque variable forme une colonne : Une seule variable par colonne
  2. Chaque observation forme une ligne : Une seule observation par ligne
  3. Chaque valeur a sa propre cellule : Une seule valeur par cellule
  4. Un type d’unité d’observation par tableau : Ne pas mélanger différents types de données

2.2.1.1 L’opérateur pipe (|>)

L’opérateur pipe (|>) est l’un des outils les plus puissants du tidyverse. Il permet de :

Principe de base :

# Au lieu d'écrire : fonction2(fonction1(donnees, argument1), argument2)
# On peut écrire : donnees |> fonction1(argument1) |> fonction2(argument2)

Exemple concret :

# Méthode traditionnelle (difficile à lire)
# resultat <- filter(select(mutate(pieges, nouveau = ancienne * 2), nouveau, site), site == 1)

# Méthode avec pipe (facile à lire et comprendre)
# resultat <- pieges |>
#   mutate(nouveau = ancienne * 2) |>
#   select(nouveau, site) |>
#   filter(site == 1)

2.2.1.2 Avantages du pipe

  1. Lisibilité améliorée : Le code se lit de gauche à droite, comme une phrase
  2. Moins d’objets intermédiaires : Évite de créer des variables temporaires
  3. Débogage facilité : On peut exécuter le code ligne par ligne
  4. Logique claire : Chaque étape de transformation est explicite

2.2.1.3 Packages principaux du tidyverse utilisés dans ce tutoriel

  • dplyr : Manipulation de données (filter, select, mutate, summarise)
  • ggplot2 : Création de graphiques élégants
  • tidyr : Restructuration des données (pivot_longer, pivot_wider)
  • readr : Lecture de fichiers de données
  • purrr : Programmation fonctionnelle
  • stringr : Manipulation de chaînes de caractères

2.2.1.4 Exemple pratique de workflow tidyverse

# Exemple typique d'un workflow tidyverse (sera détaillé plus tard)
# donnees |>                           # Prendre les données
#   filter(condition) |>               # Filtrer selon une condition
#   mutate(nouvelle_variable = ...) |> # Créer une nouvelle variable
#   group_by(groupe) |>                # Grouper par une variable
#   summarise(moyenne = mean(...)) |>  # Calculer des statistiques
#   ggplot(aes(x = ..., y = ...)) +    # Créer un graphique
#   geom_point()                       # Ajouter des points

Pourquoi adopter cette approche ? - Efficacité : Moins de code, plus de clarté - Reproductibilité : Code plus facile à comprendre et à maintenir - Apprentissage : Syntaxe cohérente entre tous les packages - Collaboration : Standard adopté par la communauté R

Cette philosophie sera omniprésente dans tout le tutoriel. Chaque manipulation de données utilisera cette approche pour maximiser la clarté et la reproductibilité du code.

2.2.2 Avantages de travailler avec des documents Quarto/R Markdown

Ce tutoriel utilise le format Quarto (extension .qmd), une évolution moderne de R Markdown. Ces formats offrent de nombreux avantages pour l’analyse de données scientifiques :

2.2.2.1 Recherche reproductible

Intégration code-texte : - Code et explications ensemble : Le code, les résultats et les explications sont dans le même document - Exécution automatique : Les graphiques et tableaux sont générés automatiquement à partir du code - Pas de copier-coller : Élimination des erreurs de transfert manuel entre logiciels

2.2.2.2 Documentation vivante

Mise à jour automatique : - Résultats toujours à jour : Quand les données changent, tout le document se met à jour - Traçabilité complète : Chaque résultat peut être retracé jusqu’au code qui l’a généré - Versions cohérentes : Impossible d’avoir des résultats qui ne correspondent pas au code

2.2.2.3 Flexibilité de sortie

Formats multiples : - HTML : Pour la visualisation interactive et le partage web - PDF : Pour les rapports formels et publications - Word : Pour la collaboration avec des collègues non-techniques - Présentations : Slides directement à partir du même code

2.2.2.4 Avantages pédagogiques

Apprentissage structuré : - Progression logique : Code et explications s’enchaînent naturellement - Contexte immédiat : Chaque bout de code est expliqué dans son contexte - Expérimentation facile : Modifier le code et voir immédiatement les résultats

2.2.2.5 Collaboration scientifique

Partage efficace : - Tout inclus : Un seul fichier contient analyse, méthodes et résultats - Contrôle de version : Compatible avec Git pour le travail d’équipe - Transparence : Les méthodes sont explicites et vérifiables

2.2.2.6 Exemple pratique

# Ce bloc de code sera exécuté et ses résultats affichés automatiquement
# Exemple simple pour démontrer l'intégration
exemple_donnees <- data.frame(
  x = 1:5,
  y = c(2, 4, 6, 8, 10)
)

# Le graphique apparaîtra directement dans le document final
# ggplot(exemple_donnees, aes(x = x, y = y)) +
#   geom_point() +
#   labs(title = "Exemple d'intégration code-résultats")

Pourquoi c’est révolutionnaire : - Fin des “ça marchait sur mon ordinateur” : L’environnement est documenté - Science ouverte : Méthodes complètement transparentes et reproductibles - Gain de temps : Plus besoin de refaire manuellement les graphiques après modifications - Qualité : Moins d’erreurs, plus de cohérence

Ce format est devenu la norme en science des données et recherche reproductible. Vous constaterez ces avantages tout au long de ce tutoriel !

2.3 Gestion des projets R et bonnes pratiques de reproductibilité

2.3.1 Importance des projets R (R Projects)

Avant de commencer l’analyse, il est crucial de comprendre l’importance d’organiser son travail dans un projet R. Un projet R crée un environnement de travail isolé et portable qui facilite la collaboration et la reproductibilité.

2.3.1.1 Problèmes avec setwd() et chemins absolus

❌ Mauvaise pratique :

# Ne jamais faire cela !
setwd("/Users/MonNom/Documents/projet_entomo/")
donnees <- read_csv("donnees/mes_donnees.csv")

Problèmes causés par setwd() :

  1. Non-reproductible : Le chemin /Users/MonNom/Documents/ n’existe que sur un ordinateur spécifique
  2. Fragile : Si le dossier est déplacé, le code ne fonctionne plus
  3. Collaboration impossible : Vos collègues ne peuvent pas exécuter votre code
  4. Maintenance difficile : Difficile de réorganiser les fichiers
  5. Erreurs fréquentes : Changements de répertoire non intentionnels

2.3.1.2 Solutions avec les projets R

✅ Bonne pratique :

# Avec un projet R, tous les chemins sont relatifs
donnees <- read_csv("donnees/mes_donnees.csv")
# ou
donnees <- read_csv(here::here("donnees", "mes_donnees.csv"))

Avantages des projets R :

  1. Reproductibilité : Le code fonctionne sur n’importe quel ordinateur
  2. Portabilité : Facile de déplacer ou partager tout le projet
  3. Organisation : Structure claire et logique des fichiers
  4. Collaboration : Plusieurs personnes peuvent travailler sur le même projet
  5. Versionning : Compatible avec Git pour le contrôle de version

2.3.1.3 Structure recommandée d’un projet d’entomologie

projet_entomo/
├── projet_entomo.Rproj        # Fichier de projet R
├── README.md                  # Documentation du projet
├── donnees/                   # Données brutes (ne jamais modifier)
│   ├── spatiales/
│   │   ├── pieges.gpkg
│   │   └── sites.gpkg
│   └── biologiques/
│       └── captures.xlsx
├── donnees_traitees/          # Données nettoyées/transformées
├── scripts/                   # Scripts R d'analyse
│   ├── 01_nettoyage.R
│   ├── 02_analyses.R
│   └── 03_visualisations.R
├── graphiques/                # Graphiques exportés
├── rapports/                  # Rapports et documents
└── fonctions/                 # Fonctions personnalisées

2.3.1.4 Le package here pour les chemins

Le package here résout élégamment les problèmes de chemins :

# Installation et chargement
install.packages("here")
library(here)

# Utilisation
donnees <- read_csv(here("donnees", "spatiales", "pieges.gpkg"))
ggsave(here("graphiques", "carte_sites.png"), plot = ma_carte)

Avantages de here() : - Trouve automatiquement la racine du projet - Fonctionne sur tous les systèmes d’exploitation - Chemins toujours relatifs au projet - Compatible avec RStudio et autres IDE

2.3.2 Workflow reproductible recommandé

  1. Créer un nouveau projet R dans RStudio
  2. Organiser les dossiers selon la structure recommandée
  3. Utiliser des chemins relatifs avec here()
  4. Documenter le projet avec un README.md
  5. Versionner avec Git pour suivre les modifications
  6. Tester la reproductibilité sur un autre ordinateur

2.3.3 Exemple pratique pour ce tutoriel

# Ce tutoriel assume que vous travaillez dans un projet R
# Tous les chemins seront relatifs, comme :
pieges <- st_read(here("donnees", "spatiales", "pieges.gpkg"))
captures <- read_xlsx(here("donnees", "biologiques", "captures.xlsx"))

# Au lieu de chemins absolus problématiques :
# pieges <- st_read("/Users/MonNom/projet/donnees/spatiales/pieges.gpkg")

Message important : Si vous voyez setwd() dans du code R, considérez-le comme un signal d’alarme pour les problèmes de reproductibilité. Préférez toujours l’approche par projets R !

3 Visualisation et personnalisation graphique

3.1 Introduction à ggplot2 et personnalisation des graphiques

3.1.1 La grammaire des graphiques avec ggplot2

ggplot2 est l’un des packages les plus puissants et populaires de R pour la création de visualisations. Il est basé sur la “Grammar of Graphics”, une approche systématique pour construire des graphiques par couches.

3.1.1.1 Anatomie d’un graphique ggplot2

# Structure de base d'un graphique ggplot2
ggplot(data = mes_donnees, aes(x = variable_x, y = variable_y)) +
  geom_point() +                    # Couche géométrique (points)
  scale_x_continuous() +            # Échelle pour l'axe X
  scale_y_continuous() +            # Échelle pour l'axe Y
  labs(title = "Mon titre") +       # Étiquettes
  theme_minimal()                   # Thème graphique

Composants principaux : 1. Données (data) : Le jeu de données à visualiser 2. Esthétiques (aes) : Mapping des variables aux propriétés visuelles 3. Géométries (geom_*) : Type de représentation (points, lignes, barres, etc.) 4. Échelles (scale_*) : Contrôle des axes et légendes 5. Étiquettes (labs) : Titres, sous-titres, légendes 6. Thèmes (theme_*) : Apparence générale du graphique

3.1.2 Thèmes ggplot2 : De la base à la personnalisation

Les thèmes contrôlent l’apparence non-liée aux données de vos graphiques. ggplot2 offre plusieurs thèmes pré-formatés ainsi que des options de personnalisation complète.

3.1.2.1 Thèmes pré-formatés utilisés dans ce tutoriel

3.1.2.2 Démonstration des différents thèmes

[1] "1. Thème par défaut (theme_gray)"
graphique_base

[1] "2. theme_minimal() - Épuré et moderne"
graphique_base + theme_minimal()

[1] "3. theme_classic() - Style traditionnel"
graphique_base + theme_classic()

[1] "4. theme_bw() - Fond blanc avec bordures"
graphique_base + theme_bw()

[1] "5. theme_void() - Minimaliste absolu"
graphique_base + theme_void()

3.1.2.3 Thèmes recommandés pour la recherche scientifique

Pour les publications scientifiques : - theme_classic() : Apparence traditionnelle, axes sans grille - theme_bw() : Fond blanc, grilles discrètes - theme_minimal() : Moderne et épuré (utilisé dans ce tutoriel)

Pour les présentations : - theme_minimal() : Lisible et moderne - theme_void() : Pour les cartes et diagrammes simples

3.1.2.4 Personnalisation avancée des thèmes

Vous pouvez modifier n’importe quel élément d’un thème avec theme() :

# Exemple de personnalisation complète
graphique_personnalise <- graphique_base +
  theme_minimal() +
  theme(
    # Titre principal
    plot.title = element_text(
      size = 16, 
      face = "bold", 
      hjust = 0.5,
      color = "darkblue"
    ),
    # Axes
    axis.title = element_text(size = 12, face = "bold"),
    axis.text = element_text(size = 10),
    axis.line = element_line(color = "black", size = 0.5),
    # Légende
    legend.position = "bottom",
    legend.title = element_text(size = 11, face = "bold"),
    legend.text = element_text(size = 10),
    # Grilles
    panel.grid.major = element_line(color = "gray90", size = 0.3),
    panel.grid.minor = element_blank(),
    # Fond
    panel.background = element_rect(fill = "white", color = NA),
    plot.background = element_rect(fill = "white", color = NA)
  )
Warning: The `size` argument of `element_line()` is deprecated as of ggplot2 3.4.0.
ℹ Please use the `linewidth` argument instead.
[1] "Graphique avec thème personnalisé :"
graphique_personnalise

3.1.2.5 Créer et réutiliser ses propres thèmes

# Créer un thème personnalisé pour l'entomologie
theme_entomo <- function() {
  theme_minimal() +
  theme(
    # Titre centré et en gras
    plot.title = element_text(size = 14, face = "bold", hjust = 0.5),
    plot.subtitle = element_text(size = 12, hjust = 0.5, color = "gray40"),
    # Axes nets et lisibles
    axis.title = element_text(size = 11, face = "bold"),
    axis.text = element_text(size = 9),
    # Légende en bas
    legend.position = "bottom",
    legend.key.size = unit(0.4, "cm"),
    # Grilles discrètes
    panel.grid.major = element_line(color = "gray90", size = 0.2),
    panel.grid.minor = element_blank(),
    # Marges optimisées
    plot.margin = unit(c(0.5, 0.5, 0.5, 0.5), "cm")
  )
}

# Utiliser le thème personnalisé
[1] "Thème personnalisé pour l'entomologie :"
graphique_base + theme_entomo()

3.1.3 Encouragement à l’expérimentation

💡 Conseil : N’hésitez pas à expérimenter avec les thèmes tout au long de ce tutoriel !

  • Remplacez theme_minimal() par theme_classic() ou theme_bw()
  • Modifiez les couleurs avec color = "votre_couleur"
  • Changez les tailles avec size = votre_taille
  • Déplacez les légendes avec legend.position = "right"/"left"/"top"/"bottom"

Ressources pour aller plus loin : - Documentation officielle : ?theme - Galerie ggplot2 : https://r-graph-gallery.com/ - Extension ggthemes : thèmes additionnels professionnels

3.1.4 Sauvegarde des graphiques avec ggsave()

La fonction ggsave() est l’outil standard pour exporter vos graphiques dans différents formats.

3.1.4.1 Syntaxe de base

# Créer un graphique
mon_graphique <- ggplot(donnees_exemple, aes(x = x, y = y)) +
  geom_point() +
  theme_minimal() +
  labs(title = "Mon graphique à sauvegarder")

# Sauvegarder le graphique
ggsave(
  filename = "mon_graphique.png",  # Nom du fichier
  plot = mon_graphique,            # Objet graphique (optionnel si dernier plot)
  width = 8,                       # Largeur en pouces
  height = 6,                      # Hauteur en pouces
  dpi = 300                        # Résolution (300 DPI pour publication)
)
[1] "Graphique sauvegardé dans mon_graphique.png"

3.1.4.2 Formats de sortie supportés

# PNG - Idéal pour le web et présentations
ggsave("graphique.png", mon_graphique, width = 8, height = 6, dpi = 300)

# PDF - Vectoriel, parfait pour les publications
ggsave("graphique.pdf", mon_graphique, width = 8, height = 6)

# SVG - Vectoriel, modifiable dans Illustrator
ggsave("graphique.svg", mon_graphique, width = 8, height = 6)

# TIFF - Format courant en recherche
ggsave("graphique.tiff", mon_graphique, width = 8, height = 6, dpi = 300)

# JPEG - Plus compressé que PNG
ggsave("graphique.jpg", mon_graphique, width = 8, height = 6, dpi = 300, quality = 95)

3.1.4.3 Conseils pour la sauvegarde

Résolutions recommandées : - 72-150 DPI : Web, présentations PowerPoint - 300 DPI : Publications scientifiques, rapports imprimés - 600 DPI : Impression haute qualité

Formats recommandés selon l’usage : - PNG : Graphiques avec transparence, usage général - PDF : Publications scientifiques (vectoriel, redimensionnable) - SVG : Retouches graphiques ultérieures - TIFF : Certaines revues scientifiques l’exigent

Dimensions typiques :

# Figure simple
ggsave("figure.png", width = 6, height = 4, dpi = 300)

# Figure large (deux colonnes)
ggsave("figure_large.png", width = 10, height = 6, dpi = 300)

# Figure carrée (pour certains graphiques)
ggsave("figure_carree.png", width = 6, height = 6, dpi = 300)

3.1.4.4 Intégration avec les projets R

# Avec le package here pour chemins relatifs
library(here)

# Sauvegarder dans le dossier graphiques du projet
ggsave(
  here("graphiques", "analyse_captures.png"),
  plot = mon_graphique,
  width = 8, height = 6, dpi = 300
)

Astuce : Créez toujours vos graphiques avec des dimensions et résolutions adaptées à leur utilisation finale !

4 Analyse spatiale et exploration des données

4.1 Chargement et préparation des données spatiales

NoteObjectif de cette section

Charger les données spatiales d’échantillonnage entomologique et les préparer pour l’analyse en uniformisant les systèmes de coordonnées.

Nous commençons par charger nos données spatiales stockées au format GeoPackage (.gpkg), un format moderne et efficace pour les données géospatiales.

4.1.1 Chargement des fichiers spatiaux

# ========================================
# CHARGEMENT DES DONNÉES SPATIALES
# ========================================

# Chargement des données spatiales depuis des fichiers GeoPackage
# GeoPackage (.gpkg) est un format moderne qui remplace Shapefile
# Il supporte plusieurs couches dans un seul fichier et préserve les métadonnées
pieges <- st_read("pieges.gpkg")                  # Lecture des données de pièges (points)
Reading layer `pieges' from data source 
  `/home/ubuntu/working_vol/personal_website/personal_website/classes/ent101_2025/pieges.gpkg' 
  using driver `GPKG'
Simple feature collection with 4 features and 14 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: -267455.8 ymin: 160281.5 xmax: -267163 ymax: 160344
Projected CRS: NAD83 / Quebec Lambert
recoltes_actives <- st_read("recoltes_actives.gpkg")  # Lecture des données de récoltes actives (lignes/polygones)
Reading layer `recoltes_actives' from data source 
  `/home/ubuntu/working_vol/personal_website/personal_website/classes/ent101_2025/recoltes_actives.gpkg' 
  using driver `GPKG'
Simple feature collection with 2 features and 12 fields
Geometry type: LINESTRING
Dimension:     XYM
Bounding box:  xmin: -267451.4 ymin: 160274.8 xmax: -267152.3 ymax: 160325.7
m_range:       mmin: 0 mmax: 0
Projected CRS: NAD83 / Quebec Lambert

4.1.2 Transformation des systèmes de coordonnées

# ========================================
# TRANSFORMATION DU SYSTÈME DE COORDONNÉES
# ========================================

# Transformation vers le système de coordonnées WGS84 (EPSG:4326)
# Cette étape est cruciale pour :
# - Compatibilité avec les services de cartes web (OpenStreetMap, Google Maps)
# - Uniformisation des systèmes de coordonnées entre couches
# - Calculs de distances et surfaces précis à l'échelle globale
pieges <- st_transform(pieges, crs = 4326)
recoltes_actives <- st_transform(recoltes_actives, crs = 4326)

# Vérification des systèmes de coordonnées après transformation
cat("Système de coordonnées des pièges:", st_crs(pieges)$input, "\n")
Système de coordonnées des pièges: EPSG:4326 
cat("Système de coordonnées des récoltes actives:", st_crs(recoltes_actives)$input, "\n")
Système de coordonnées des récoltes actives: EPSG:4326 
TipFonctions clés utilisées
  • st_read() : Lit les fichiers de données spatiales (shapefile, gpkg, etc.)
  • st_transform() : Change le système de coordonnées des données spatiales
  • st_crs() : Affiche le système de référence de coordonnées

4.2 Pourquoi EPSG:4326 ?

Le système WGS84 (EPSG:4326) utilise des coordonnées latitude/longitude et est compatible avec les services de cartes web comme OpenStreetMap. C’est essentiel pour superposer nos données avec des fonds de carte.

4.3 Étape 1: Exploration des données

NoteImportance de l’exploration des données

Avant toute analyse, il est crucial d’explorer la distribution de nos variables clés pour détecter des valeurs aberrantes et comprendre la structure des données.

4.3.1 Distribution de la couverture arborescente

# ========================================
# EXPLORATION GRAPHIQUE DES DONNÉES
# ========================================

# Création d'un histogramme pour comprendre la distribution de la couverture arborescente
# Cette étape est essentielle pour :
# - Détecter des valeurs aberrantes ou incohérentes
# - Comprendre la variabilité de l'environnement d'étude
# - Planifier les analyses ultérieures (groupement, classification)
pieges |>  # Utilisation du pipe pour un code lisible
  ggplot(aes(x = couverture_arborescente)) +  # Mapping de la variable sur l'axe X
  geom_histogram(
    binwidth = 1,                    # Largeur des barres : 1% de couverture
    fill = "steelblue3",            # Couleur de remplissage des barres
    color = "white",                # Couleur des bordures
    alpha = 0.7                     # Transparence pour un effet visuel agréable
  ) +
  labs(
    y = "Fréquence",               # Étiquette de l'axe Y
    x = "% Couverture arborescente", # Étiquette de l'axe X
    title = "Distribution de la couverture arborescente",
    subtitle = "Fréquence observée pour les sites de pièges",
    caption = "Source: Données terrain - Analyse exploratoire"
  ) +
  theme_classic() +                # Thème propre pour publication
  theme(
    plot.title = element_text(size = 12, face = "bold"),
    plot.subtitle = element_text(size = 10, color = "gray40")
  )
Figure 2: Distribution de la couverture arborescente pour les sites de pièges. L’histogramme révèle une distribution bimodale suggérant deux types d’habitats distincts.
TipInterprétation de l’histogramme

L’histogramme révèle une distribution bimodale de la couverture arborescente, suggérant naturellement deux types d’habitats distincts. Cette observation guidera notre stratégie de classification des sites.

4.4 Classification des sites par habitat

NoteObjectif de la classification

Basé sur la distribution observée, nous créons deux groupes de sites selon leur couverture arborescente pour faciliter les analyses comparatives entre habitats.

4.4.1 Classification automatisée

Basé sur la distribution observée, nous créons deux groupes de sites selon leur couverture arborescente.

Table 1: Classification des sites selon l’habitat basée sur la couverture arborescente
# ========================================
# CLASSIFICATION DES SITES SELON L'HABITAT
# ========================================

# Classification basée sur un seuil écologiquement pertinent (40% de couverture)
# Cette classification permet de :
# - Distinguer les habitats forestiers (>40%) des habitats ouverts (≤40%)
# - Créer des groupes pour analyses comparatives
# - Simplifier l'interprétation écologique des résultats
pieges <- pieges |>
  mutate(
    site = ifelse(
      couverture_arborescente > 40,  # Condition de test
      1,                             # Valeur si condition vraie (habitat forestier)
      2                              # Valeur si condition fausse (habitat ouvert)
    ),
    # Ajout d'une variable textuelle pour faciliter l'interprétation
    type_habitat = case_when(
      couverture_arborescente > 40 ~ "Forestier",
      couverture_arborescente <= 40 ~ "Ouvert",
      .default = "Non classé"  # Gestion des valeurs manquantes
    )
  )

4.4.2 Vérification de la classification

Code
# Vérification de la classification
verification_classification <- pieges |>
  st_drop_geometry() |>  # Suppression de la géométrie pour affichage tabulaire
  group_by(site, type_habitat) |>
  summarise(
    n_sites = n(),                                    # Nombre de sites par catégorie
    couverture_min = min(couverture_arborescente),   # Couverture minimale
    couverture_max = max(couverture_arborescente),   # Couverture maximale
    couverture_moyenne = round(mean(couverture_arborescente), 1), # Couverture moyenne
    .groups = "drop"
  )
[1] "Résumé de la classification des habitats:"
# A tibble: 2 × 6
   site type_habitat n_sites couverture_min couverture_max couverture_moyenne
  <dbl> <chr>          <int>          <int>          <int>              <dbl>
1     1 Forestier          2             75             80               77.5
2     2 Ouvert             2              0             20               10  

Statistiques descriptives de la classification des habitats selon la couverture arborescente.

TipLogique de classification

Le seuil de 40% de couverture arborescente divise naturellement nos sites en deux groupes écologiquement pertinents :

  • Site 1 (Forestier) : Zones avec >40% de couverture (habitats fermés)
  • Site 2 (Ouvert) : Zones avec ≤40% de couverture (habitats ouverts)

Cette classification nous permettra de comparer les communautés d’insectes entre habitats contrastés.

4.5 Étape 2: Vérification de la classification

Nous appliquons la même logique aux données de récoltes actives pour vérifier la cohérence de notre classification.

# Histogramme de la couverture arborescente pour les récoltes actives
recoltes_actives |>
  ggplot(aes(x = couverture_arborescente)) +
  geom_histogram(binwidth = 1, fill = "coral3", color = "white", alpha = 0.7) +
  labs(y = "Fréquence", 
       x = "% Couverture arborescente",
       title = "Distribution de la couverture arborescente (récoltes actives)",
       subtitle = "Vérification de la cohérence avec les sites de pièges") +
  theme_classic() +
  theme(
    plot.title = element_text(size = 12, face = "bold"),
    plot.subtitle = element_text(size = 10, color = "gray40")
  )
Figure 3: Distribution de la couverture arborescente pour les sites de récoltes actives. La distribution similaire à celle des pièges confirme la cohérence de notre échantillonnage.

Ce second histogramme nous permet de vérifier que la distribution de la couverture arborescente est similaire entre les deux méthodes d’échantillonnage (pièges vs récoltes actives).

# Application de la même classification de sites aux récoltes actives
recoltes_actives <- recoltes_actives |>
                      mutate(site = ifelse(couverture_arborescente > 40, 1, 2))

4.6 Étape 3: Préparation de la cartographie

Avant de créer nos cartes, nous devons calculer l’étendue spatiale de nos données pour déterminer la zone à afficher.

# Calcul de l'étendue spatiale combinée des deux jeux de données
bbox_combined <- st_bbox(c(st_geometry(pieges), st_geometry(recoltes_actives)))

# Ajout d'un tampon à l'étendue spatiale (en degrés décimaux)
buffer_deg <- 0.005  # Tampon plus petit pour une carte contextuelle plus focalisée

# Création de l'étendue tampon
bbox_buffered <- bbox_combined
bbox_buffered["xmin"] <- bbox_combined["xmin"] - buffer_deg
bbox_buffered["ymin"] <- bbox_combined["ymin"] - buffer_deg
bbox_buffered["xmax"] <- bbox_combined["xmax"] + buffer_deg
bbox_buffered["ymax"] <- bbox_combined["ymax"] + buffer_deg
[1] "Étendue originale:"
     xmin      ymin      xmax      ymax 
-71.91162  45.38089 -71.90777  45.38162 
[1] "Étendue avec tampon:"
     xmin      ymin      xmax      ymax 
-71.91662  45.37589 -71.90277  45.38662 

Fonctions utilisées : - st_bbox() : Calcule l’étendue spatiale (bounding box) des données - st_geometry() : Extrait uniquement la géométrie des objets spatiaux - c() : Combine plusieurs objets

Pourquoi un tampon (buffer) ? Le tampon ajoute de l’espace autour de nos données pour : 1. Éviter que les points touchent les bords de la carte 2. Fournir du contexte spatial 3. Améliorer l’esthétique de la carte

Note sur les unités : 0.008 degrés décimaux ≈ 800 mètres à cette latitude.

4.7 Étape 4: Création de la carte principale

Nous créons maintenant une carte détaillée montrant nos sites d’échantillonnage avec différents symboles et couleurs selon le type de piège et le site.

Références utiles pour la personnalisation des graphiques: Formes de points: https://blog.albertkuo.me/post/point-shape-options-in-ggplot/ Types de lignes: https://r-charts.com/base-r/line-types/ Couleurs: https://www.nceas.ucsb.edu/sites/default/files/2020-04/colorPaletteCheatsheet.pdf

4.8 Cartographie avancée avec ggplot2 et ggspatial

La cartographie avec R permet de créer des cartes de qualité publication. Nous allons utiliser ggplot2 combiné avec ggspatial pour ajouter des fonds de carte.

# ========================================
# CRÉATION D'UNE CARTE DÉTAILLÉE AVEC FOND CARTOGRAPHIQUE
# ========================================

# Création de la carte principale avec superposition de données vectorielles et raster
# Cette approche permet de :
# - Contextualiser géographiquement les données d'échantillonnage
# - Visualiser les relations spatiales entre différents types de données
# - Créer des cartes de qualité publication pour rapports scientifiques
main_map <- ggplot() +
  
  # ========================================
  # FOND DE CARTE (TUILES RASTER)
  # ========================================
  # Ajout des tuiles OpenStreetMap comme fond cartographique
  # - type = "osm" : utilise OpenStreetMap (gratuit, détaillé)
  # - zoom = 18 : niveau de détail élevé (1-19, plus élevé = plus détaillé)
  annotation_map_tile(type = "osm", zoom = 18) +
  
  # ========================================
  # COUCHES DE DONNÉES SPATIALES
  # ========================================
  
  # Ajout des géométries linéaires (transects de récoltes actives)
  # Ces lignes représentent les parcours d'échantillonnage actif
  geom_sf(
    data = recoltes_actives,        # Source des données
    aes(
      color = as.factor(site),      # Couleur selon le site (facteur pour couleurs discrètes)
      linetype = type_recolte       # Type de ligne selon la méthode de récolte
    ),
    linewidth = 1.5,                # Épaisseur des lignes (visible sur le fond)
    alpha = 0.7                     # Transparence pour éviter la surcharge visuelle
  ) +
  
  # Ajout des géométries ponctuelles (emplacements des pièges)
  # Ces points représentent les positions exactes des pièges passifs
  geom_sf(
    data = pieges,                  # Source des données
    aes(
      color = as.factor(site),      # Couleur selon le site (cohérence avec les lignes)
      shape = type_de_piege         # Forme selon le type de piège
    ),
    size = 3,                       # Taille des points (lisibilité)
    alpha = 0.8                     # Légère transparence pour l'esthétique
  ) +
  
  # ========================================
  # CONFIGURATION DES ÉCHELLES VISUELLES
  # ========================================
  
  # Configuration des couleurs pour les sites
  # Utilisation de couleurs contrastées et accessibles
  scale_color_manual(
    values = c("royalblue3", "mediumorchid3"),  # Couleurs distinctives
    name = "Site",                               # Nom de la légende
    labels = c("Site 1 (Forestier)", "Site 2 (Ouvert)")  # Étiquettes explicites
  ) +
  # Configuration des formes pour les types de pièges
  scale_shape_manual(values = c(15, 18),
                     labels = c("Bol Jaune", "Malaise"),
                     name = "Type de piège") +
  # Configuration des types de lignes pour les récoltes actives
  scale_linetype_manual(values = c("dashed"),
                        labels = c("Filet Fauchoir"),
                        name = "Récoltes actives") +
  labs(title = "Pièges et Récoltes Actives - Vue détaillée") +
  theme(plot.title = element_text(hjust = 0.5, size = 14),
        legend.position = "bottom",
        legend.direction = "horizontal",
        legend.key = element_blank())

Fonctions cartographiques clés : - annotation_map_tile() : Ajoute un fond de carte (ici OpenStreetMap) - geom_sf() : Affiche les données spatiales (points, lignes, polygones) - scale_color_manual() : Contrôle les couleurs utilisées - scale_shape_manual() : Contrôle les formes des points - scale_linetype_manual() : Contrôle les types de lignes

Paramètres de zoom : Le zoom 18 fournit un niveau de détail élevé, idéal pour des études à l’échelle locale.

4.9 Étape 5: Création de la carte contextuelle

Pour situer notre zone d’étude dans un contexte plus large, nous créons une carte d’ensemble (inset map).

# Création de la carte contextuelle montrant la région de Sherbrooke
# Création d'un polygone d'étendue plus large pour forcer une vue élargie
larger_extent <- st_polygon(list(rbind(
  c(bbox_buffered["xmin"], bbox_buffered["ymin"]),
  c(bbox_buffered["xmax"], bbox_buffered["ymin"]),
  c(bbox_buffered["xmax"], bbox_buffered["ymax"]),
  c(bbox_buffered["xmin"], bbox_buffered["ymax"]),
  c(bbox_buffered["xmin"], bbox_buffered["ymin"])
))) |>
  st_sfc(crs = 4326)

# Création d'un polygone rectangulaire pour la zone d'étude
study_area_rect <- st_polygon(list(rbind(
  c(bbox_combined["xmin"], bbox_combined["ymin"]),
  c(bbox_combined["xmax"], bbox_combined["ymin"]),
  c(bbox_combined["xmax"], bbox_combined["ymax"]),
  c(bbox_combined["xmin"], bbox_combined["ymax"]),
  c(bbox_combined["xmin"], bbox_combined["ymin"])
))) |>
  st_sfc(crs = 4326)

inset_map <- ggplot() +
  # Ajout des tuiles de fond (zoom réduit pour petite zone)
  annotation_map_tile(type = "osm", zoom = 18) +
  # Ajout d'un polygone d'étendue invisible pour forcer des limites plus larges
  geom_sf(data = larger_extent, fill = NA, color = NA) +
  # Ajout du rectangle montrant l'étendue originale (zone d'étude) comme polygone sf
  geom_sf(data = study_area_rect,
          fill = "red", color = "darkred", alpha = 0.3, linewidth = 1) +
  # Ajout de la flèche du nord
  annotation_north_arrow(location = "tr", which_north = "true", 
                         pad_x = unit(0.1, "in"), pad_y = unit(0.1, "in"),
                         style = north_arrow_fancy_orienteering(),
                         height = unit(0.3, "in"), width = unit(0.2, "in")) +
  labs(title = "Réserve naturelle du Mont-Bellevue") +
  theme(plot.title = element_text(hjust = 0.5, size = 8),
        plot.background = element_rect(fill = "white", color = "black", linewidth = 1),
        axis.text = element_text(size = 4),
        plot.margin = margin(5, 5, 5, 5),
        aspect.ratio = 0.5)  # Forcer un ratio d'aspect plus large

# Combinaison des cartes en utilisant patchwork
combined_map <- main_map + 
  inset_element(inset_map, 
                left = 0.01, bottom = 0.05, 
                right = 0.99, top = 0.6)

# Affichage de la carte combinée
combined_map
Zoom: 18
Fetching 8 missing tiles

  |                                                                            
  |                                                                      |   0%
  |                                                                            
  |=========                                                             |  12%
  |                                                                            
  |==================                                                    |  25%
  |                                                                            
  |==========================                                            |  38%
  |                                                                            
  |===================================                                   |  50%
  |                                                                            
  |============================================                          |  62%
  |                                                                            
  |====================================================                  |  75%
  |                                                                            
  |=============================================================         |  88%
  |                                                                            
  |======================================================================| 100%
...complete!
Zoom: 18
Fetching 148 missing tiles

  |                                                                            
  |                                                                      |   0%
  |                                                                            
  |                                                                      |   1%
  |                                                                            
  |=                                                                     |   1%
  |                                                                            
  |=                                                                     |   2%
  |                                                                            
  |==                                                                    |   3%
  |                                                                            
  |===                                                                   |   4%
  |                                                                            
  |===                                                                   |   5%
  |                                                                            
  |====                                                                  |   5%
  |                                                                            
  |====                                                                  |   6%
  |                                                                            
  |=====                                                                 |   7%
  |                                                                            
  |======                                                                |   8%
  |                                                                            
  |======                                                                |   9%
  |                                                                            
  |=======                                                               |   9%
  |                                                                            
  |=======                                                               |  10%
  |                                                                            
  |========                                                              |  11%
  |                                                                            
  |=========                                                             |  12%
  |                                                                            
  |=========                                                             |  13%
  |                                                                            
  |=========                                                             |  14%
  |                                                                            
  |==========                                                            |  14%
  |                                                                            
  |==========                                                            |  15%
  |                                                                            
  |===========                                                           |  16%
  |                                                                            
  |============                                                          |  17%
  |                                                                            
  |============                                                          |  18%
  |                                                                            
  |=============                                                         |  18%
  |                                                                            
  |=============                                                         |  19%
  |                                                                            
  |==============                                                        |  20%
  |                                                                            
  |===============                                                       |  21%
  |                                                                            
  |===============                                                       |  22%
  |                                                                            
  |================                                                      |  22%
  |                                                                            
  |================                                                      |  23%
  |                                                                            
  |=================                                                     |  24%
  |                                                                            
  |==================                                                    |  25%
  |                                                                            
  |==================                                                    |  26%
  |                                                                            
  |===================                                                   |  27%
  |                                                                            
  |===================                                                   |  28%
  |                                                                            
  |====================                                                  |  28%
  |                                                                            
  |====================                                                  |  29%
  |                                                                            
  |=====================                                                 |  30%
  |                                                                            
  |======================                                                |  31%
  |                                                                            
  |======================                                                |  32%
  |                                                                            
  |=======================                                               |  32%
  |                                                                            
  |=======================                                               |  33%
  |                                                                            
  |========================                                              |  34%
  |                                                                            
  |=========================                                             |  35%
  |                                                                            
  |=========================                                             |  36%
  |                                                                            
  |==========================                                            |  36%
  |                                                                            
  |==========================                                            |  37%
  |                                                                            
  |==========================                                            |  38%
  |                                                                            
  |===========================                                           |  39%
  |                                                                            
  |============================                                          |  40%
  |                                                                            
  |============================                                          |  41%
  |                                                                            
  |=============================                                         |  41%
  |                                                                            
  |=============================                                         |  42%
  |                                                                            
  |==============================                                        |  43%
  |                                                                            
  |===============================                                       |  44%
  |                                                                            
  |===============================                                       |  45%
  |                                                                            
  |================================                                      |  45%
  |                                                                            
  |================================                                      |  46%
  |                                                                            
  |=================================                                     |  47%
  |                                                                            
  |==================================                                    |  48%
  |                                                                            
  |==================================                                    |  49%
  |                                                                            
  |===================================                                   |  49%
  |                                                                            
  |===================================                                   |  50%
  |                                                                            
  |===================================                                   |  51%
  |                                                                            
  |====================================                                  |  51%
  |                                                                            
  |====================================                                  |  52%
  |                                                                            
  |=====================================                                 |  53%
  |                                                                            
  |======================================                                |  54%
  |                                                                            
  |======================================                                |  55%
  |                                                                            
  |=======================================                               |  55%
  |                                                                            
  |=======================================                               |  56%
  |                                                                            
  |========================================                              |  57%
  |                                                                            
  |=========================================                             |  58%
  |                                                                            
  |=========================================                             |  59%
  |                                                                            
  |==========================================                            |  59%
  |                                                                            
  |==========================================                            |  60%
  |                                                                            
  |===========================================                           |  61%
  |                                                                            
  |============================================                          |  62%
  |                                                                            
  |============================================                          |  63%
  |                                                                            
  |============================================                          |  64%
  |                                                                            
  |=============================================                         |  64%
  |                                                                            
  |=============================================                         |  65%
  |                                                                            
  |==============================================                        |  66%
  |                                                                            
  |===============================================                       |  67%
  |                                                                            
  |===============================================                       |  68%
  |                                                                            
  |================================================                      |  68%
  |                                                                            
  |================================================                      |  69%
  |                                                                            
  |=================================================                     |  70%
  |                                                                            
  |==================================================                    |  71%
  |                                                                            
  |==================================================                    |  72%
  |                                                                            
  |===================================================                   |  72%
  |                                                                            
  |===================================================                   |  73%
  |                                                                            
  |====================================================                  |  74%
  |                                                                            
  |====================================================                  |  75%
  |                                                                            
  |=====================================================                 |  76%
  |                                                                            
  |======================================================                |  77%
  |                                                                            
  |======================================================                |  78%
  |                                                                            
  |=======================================================               |  78%
  |                                                                            
  |=======================================================               |  79%
  |                                                                            
  |========================================================              |  80%
  |                                                                            
  |=========================================================             |  81%
  |                                                                            
  |=========================================================             |  82%
  |                                                                            
  |==========================================================            |  82%
  |                                                                            
  |==========================================================            |  83%
  |                                                                            
  |===========================================================           |  84%
  |                                                                            
  |============================================================          |  85%
  |                                                                            
  |============================================================          |  86%
  |                                                                            
  |=============================================================         |  86%
  |                                                                            
  |=============================================================         |  87%
  |                                                                            
  |=============================================================         |  88%
  |                                                                            
  |==============================================================        |  89%
  |                                                                            
  |===============================================================       |  90%
  |                                                                            
  |===============================================================       |  91%
  |                                                                            
  |================================================================      |  91%
  |                                                                            
  |================================================================      |  92%
  |                                                                            
  |=================================================================     |  93%
  |                                                                            
  |==================================================================    |  94%
  |                                                                            
  |==================================================================    |  95%
  |                                                                            
  |===================================================================   |  95%
  |                                                                            
  |===================================================================   |  96%
  |                                                                            
  |====================================================================  |  97%
  |                                                                            
  |===================================================================== |  98%
  |                                                                            
  |===================================================================== |  99%
  |                                                                            
  |======================================================================|  99%
  |                                                                            
  |======================================================================| 100%
...complete!
Figure 4: Carte combinée des sites d’échantillonnage entomologique avec vue détaillée et carte contextuelle. La carte principale montre les pièges et transects de récolte active avec fond OpenStreetMap, tandis que l’encart situe la zone d’étude dans la réserve naturelle du Mont-Bellevue.

Cette carte n’est pas parfaite pour une publication mais sera satisfaisante dans le cadre du rapport.

TipComment fonctionne patchwork pour combiner les cartes

Le package patchwork simplifie énormément la combinaison de graphiques ggplot2. Dans notre exemple :

Syntaxe de base : - main_map + inset_element(inset_map, ...) combine les deux cartes - L’opérateur + de patchwork ajoute l’inset comme élément superposé

Paramètres de inset_element() : - left = 0.05 : Position du bord gauche de l’inset (5% de la largeur totale) - bottom = 0.05 : Position du bord inférieur (5% de la hauteur totale)
- right = 0.95 : Position du bord droit (95% de la largeur totale) - top = 0.6 : Position du bord supérieur (60% de la hauteur totale)

Ces coordonnées utilisent un système de coordonnées normalisées (0 à 1) où : - (0,0) = coin inférieur gauche de la carte principale - (1,1) = coin supérieur droit de la carte principale

Avantages de patchwork : - Syntaxe intuitive et lisible - Contrôle précis du positionnement - Maintien de la qualité graphique - Compatible avec tous les thèmes ggplot2

4.10 Étape 6: Extraction des coordonnées des pièges malaise

Nous allons extraire les coordonnées des pièges malaises des deux sites qui représentent approximativement les points centroides des sites.

# Filtrage des pièges malaise
malaise_traps <- pieges |>
  filter(type_de_piege == "malaise")

# Extraction des coordonnées
malaise_coords <- malaise_traps |>
  st_coordinates() |>
  as_tibble() |>
  rename(longitude = X, latitude = Y)

# Combinaison avec les données originales (sans géométrie)
malaise_with_coords <- malaise_traps |>
  st_drop_geometry() |>
  bind_cols(malaise_coords) |>
  select(site, longitude, latitude)

glimpse(malaise_with_coords)
Rows: 2
Columns: 3
$ site      <dbl> 1, 2
$ longitude <dbl> -71.90850, -71.91099
$ latitude  <dbl> 45.38122, 45.38095

Fonctions utilisées : - filter() : Sélectionne uniquement les lignes correspondant à un critère - st_coordinates() : Extrait les coordonnées X,Y des objets spatiaux - as_tibble() : Convertit en format tibble (data frame moderne) - st_drop_geometry() : Supprime la géométrie spatiale pour garder seulement les attributs - bind_cols() : Combine les colonnes de deux data frames - rename() : Renomme les colonnes pour plus de clarté

Pourquoi extraire les coordonnées ? Les coordonnées seront utilisées pour récupérer les données météorologiques spécifiques à chaque site d’échantillonnage via l’API NASA POWER.

5 Analyse temporelle et données météorologiques

5.1 Étape 7: Analyse temporelle des données d’échantillonnage

L’analyse temporelle est cruciale pour comprendre les périodes d’activité des insectes et synchroniser nos données avec les conditions météorologiques. Nous utilisons la librairie lubridate qui simplifie grandement la manipulation des dates et heures en R.

library(lubridate)  # Bibliothèque pour la manipulation de dates

# Analyse temporelle des données de pièges
pieges <- pieges |>
  mutate(
    # Analyse de date_pose (date de pose des pièges)
    date_pose_parsed = ymd_hms(date_pose),
    date_pose_date = date(date_pose_parsed),
    date_pose_time = hms::as_hms(date_pose_parsed),
    date_pose_year = year(date_pose_parsed),
    date_pose_month = month(date_pose_parsed),
    date_pose_day = day(date_pose_parsed),
    date_pose_hour = hour(date_pose_parsed),
    date_pose_minute = minute(date_pose_parsed),
    
    # Analyse de date_recolte (date de récolte)
    date_recolte_parsed = ymd_hms(date_recolte),
    date_recolte_date = date(date_recolte_parsed),
    date_recolte_time = hms::as_hms(date_recolte_parsed),
    date_recolte_year = year(date_recolte_parsed),
    date_recolte_month = month(date_recolte_parsed),
    date_recolte_day = day(date_recolte_parsed),
    date_recolte_hour = hour(date_recolte_parsed),
    date_recolte_minute = minute(date_recolte_parsed),
    
    # Analyse de date_retrait (date de retrait des pièges)
    date_retrait_parsed = ymd_hms(date_retrait),
    date_retrait_date = date(date_retrait_parsed),
    date_retrait_time = hms::as_hms(date_retrait_parsed),
    date_retrait_year = year(date_retrait_parsed),
    date_retrait_month = month(date_retrait_parsed),
    date_retrait_day = day(date_retrait_parsed),
    date_retrait_hour = hour(date_retrait_parsed),
    date_retrait_minute = minute(date_retrait_parsed)
  )

# Affichage du résumé des dates analysées
pieges |>
  st_drop_geometry() |>
  select(contains("_parsed"), contains("_date"), contains("_time")) |>
  glimpse()
Rows: 4
Columns: 9
$ date_pose_parsed    <dttm> 2025-06-29 12:45:00, 2025-06-29 12:45:00, 2025-06…
$ date_recolte_parsed <dttm> 2025-07-01 13:00:00, 2025-07-05 13:00:00, 2025-07…
$ date_retrait_parsed <dttm> 2025-07-05 13:39:28, 2025-07-05 13:39:33, 2025-07…
$ date_pose_date      <date> 2025-06-29, 2025-06-29, 2025-06-29, 2025-06-29
$ date_recolte_date   <date> 2025-07-01, 2025-07-05, 2025-07-01, 2025-07-01
$ date_retrait_date   <date> 2025-07-05, 2025-07-05, 2025-07-05, 2025-07-05
$ date_pose_time      <time> 12:45:00.000, 12:45:00.587, 12:45:00.555, 12:45:0…
$ date_recolte_time   <time> 13:00:00.000, 13:00:00.016, 13:00:00.121, 13:00:0…
$ date_retrait_time   <time> 13:39:28.509001, 13:39:33.799999, 13:39:28.778999…

Fonctions temporelles clés : - ymd_hms() : Parse une date au format Année-Mois-Jour Heure:Minute:Seconde - date() : Extrait seulement la partie date (sans l’heure) - year(), month(), day() : Extraient les composantes de date - hour(), minute() : Extraient les composantes d’heure - hms::as_hms() : Convertit en format heure:minute:seconde

Avantages de lubridate : Cette librairie gère automatiquement les fuseaux horaires, les années bissextiles, et offre une syntaxe intuitive pour manipuler les dates.

5.2 Étape 8: Récupération des données météorologiques

Les données météorologiques sont essentielles pour comprendre l’activité des insectes. Nous utilisons l’API NASA POWER qui fournit des données météorologiques de haute qualité, validées scientifiquement et disponibles gratuitement.

6 Données météorologiques

6.1 Site 1

Pour chaque site, nous devons d’abord extraire les coordonnées précises, puis interroger l’API NASA POWER avec les bons paramètres.

# Extraction de la latitude unique pour le site 1
lat_1 <- pieges |>
  filter(type_de_piege == "malaise") |>
  filter(site == 1) |>
  st_coordinates() |>
  as_tibble() |>
  pull(Y) |>
  unique()

# Extraction de la longitude unique pour le site 1  
lon_1 <- pieges |>
  filter(type_de_piege == "malaise") |>
  filter(site == 1) |>
  st_coordinates() |>
  as_tibble() |>
  pull(X) |>
  unique()

# Affichage des coordonnées extraites pour vérification
[1] "Latitude (Y): 45.3812188221423"
[1] "Longitude (X): -71.9084976522116"
# Note: get_power() attend lonlat = c(longitude, latitude)
meteo_site_1 <- get_power(community = "ag",
                          temporal_api = "hourly",
                          lonlat = c(lon_1, lat_1),  # longitude d'abord, puis latitude
                          dates = c("2025-06-02", "2025-06-11"),
                          pars = c("TS", "PRECTOTCORR"))

glimpse(meteo_site_1)
Rows: 240
Columns: 8
$ LON         <dbl> -71.9085, -71.9085, -71.9085, -71.9085, -71.9085, -71.9085…
$ LAT         <dbl> 45.38122, 45.38122, 45.38122, 45.38122, 45.38122, 45.38122…
$ YEAR        <dbl> 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025…
$ MO          <dbl> 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6…
$ DY          <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2…
$ HR          <dbl> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, …
$ TS          <dbl> 6.73, 6.68, 6.62, 6.61, 6.69, 7.05, 7.70, 9.09, 11.67, 13.…
$ PRECTOTCORR <dbl> 0.95, 0.79, 0.66, 0.43, 0.21, 0.10, 0.05, 0.02, 0.01, 0.01…

Paramètres de l’API NASA POWER : - community = "ag" : Communauté agricole (optimisée pour applications terrestres) - temporal_api = "hourly" : Données horaires (plus de précision) - lonlat = c(lon, lat) : Coordonnées (attention à l’ordre : longitude PUIS latitude) - dates = c("début", "fin") : Période d’intérêt - pars = c("TS", "PRECTOTCORR") : Paramètres demandés (température et précipitations)

Variables météorologiques : - TS : Température de l’air à 2 mètres (°C) - PRECTOTCORR : Précipitations totales corrigées (mm/heure)

6.2 Étape 9: Conversion des fuseaux horaires

Les données NASA POWER sont fournies en temps universel coordonné (UTC). Pour notre étude au Québec, nous devons convertir vers l’heure locale (UTC-4 en été).

# Conversion du temps UTC vers UTC-4 (heure avancée de l'Est)
# D'abord, débogage des données originales
[1] "Structure des données originales:"
 num [1:240] 2 2 2 2 2 2 2 2 2 2 ...
NULL
 num [1:240] 0 1 2 3 4 5 6 7 8 9 ...
NULL
[1] "Valeurs échantillons DY:"
[1] 2 2 2 2 2 2
[1] "Valeurs échantillons HR:"
[1] 0 1 2 3 4 5
meteo_site_1 <- meteo_site_1 |>
  mutate(
    # Débogage: vérification de l'opération de collage
    datetime_string = paste(DY, sprintf("%02d:00:00", HR)),
    
    # Utilisation des colonnes YEAR et MO réelles des données NASA POWER
    datetime_utc = ISOdate(year = YEAR, 
                          month = MO, 
                          day = DY, 
                          hour = HR, 
                          min = 0, 
                          sec = 0, 
                          tz = "UTC"),
    
    # Conversion vers UTC-4 (heure avancée de l'Est) - soustraction de 4 heures en secondes
    datetime_local = datetime_utc - (4 * 3600),
    
    # Extraction du jour et de l'heure locaux
    DY_local = as.Date(datetime_local),
    HR_local = as.numeric(format(datetime_local, "%H"))
  )

# Affichage des données converties
print("Après conversion:")
[1] "Après conversion:"
print("Échantillons datetime_string:")
[1] "Échantillons datetime_string:"
print(head(meteo_site_1$datetime_string))
[1] "2 00:00:00" "2 01:00:00" "2 02:00:00" "2 03:00:00" "2 04:00:00"
[6] "2 05:00:00"
print("Échantillons datetime_utc:")
[1] "Échantillons datetime_utc:"
print(head(meteo_site_1$datetime_utc))
[1] "2025-06-02 00:00:00 UTC" "2025-06-02 01:00:00 UTC"
[3] "2025-06-02 02:00:00 UTC" "2025-06-02 03:00:00 UTC"
[5] "2025-06-02 04:00:00 UTC" "2025-06-02 05:00:00 UTC"
print("Échantillons datetime_local:")
[1] "Échantillons datetime_local:"
print(head(meteo_site_1$datetime_local))
[1] "2025-06-01 20:00:00 UTC" "2025-06-01 21:00:00 UTC"
[3] "2025-06-01 22:00:00 UTC" "2025-06-01 23:00:00 UTC"
[5] "2025-06-02 00:00:00 UTC" "2025-06-02 01:00:00 UTC"
glimpse(meteo_site_1)
Rows: 240
Columns: 13
$ LON             <dbl> -71.9085, -71.9085, -71.9085, -71.9085, -71.9085, -71.…
$ LAT             <dbl> 45.38122, 45.38122, 45.38122, 45.38122, 45.38122, 45.3…
$ YEAR            <dbl> 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, …
$ MO              <dbl> 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, …
$ DY              <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, …
$ HR              <dbl> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, …
$ TS              <dbl> 6.73, 6.68, 6.62, 6.61, 6.69, 7.05, 7.70, 9.09, 11.67,…
$ PRECTOTCORR     <dbl> 0.95, 0.79, 0.66, 0.43, 0.21, 0.10, 0.05, 0.02, 0.01, …
$ datetime_string <chr> "2 00:00:00", "2 01:00:00", "2 02:00:00", "2 03:00:00"…
$ datetime_utc    <dttm> 2025-06-02 00:00:00, 2025-06-02 01:00:00, 2025-06-02 …
$ datetime_local  <dttm> 2025-06-01 20:00:00, 2025-06-01 21:00:00, 2025-06-01 …
$ DY_local        <date> 2025-06-01, 2025-06-01, 2025-06-01, 2025-06-01, 2025-…
$ HR_local        <dbl> 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, …

Conversion de fuseau horaire : - ISOdate() : Crée un objet date-heure en spécifiant le fuseau horaire - 4 * 3600 : 4 heures converties en secondes (3600 sec/heure) - as.Date() : Extrait seulement la date locale - format(datetime, "%H") : Extrait l’heure au format 24h

Pourquoi convertir les fuseaux horaires ? La conversion permet d’aligner les données météorologiques avec les heures locales d’activité des insectes et de nos activités d’échantillonnage.

6.3 Étape 10: Préparation des données pour visualisation

Nous simplifions et renommons les données météorologiques pour faciliter la création de graphiques.

# Nettoyage et renommage des données météorologiques
meteo_site_1 <- meteo_site_1 |>
                 rename(temp = TS,              # Température
                        precip = PRECTOTCORR) |> # Précipitations corrigées
                 select(DY_local, HR_local, temp, precip)

Simplification des données : - rename() : Donne des noms plus courts et explicites aux variables - select() : Garde seulement les colonnes nécessaires pour la visualisation

Cette étape améliore la lisibilité du code et réduit la taille des données en mémoire.

6.4 Étape 11: Visualisation des profils de température

Les graphiques temporels nous permettent d’identifier les patterns de température pendant la période d’échantillonnage et de corréler l’activité des insectes avec les conditions météorologiques.

# Graphique de température pour le Site 1
ggplot(meteo_site_1, aes(x = DY_local, y = temp)) +
  # Lignes verticales pour marquer les dates importantes d'échantillonnage
  geom_vline(xintercept = as.Date("2025-06-03"), linetype = "dashed", color = "black", linewidth = 1, alpha = 0.8) +
  geom_vline(xintercept = as.Date("2025-06-06"), linetype = "dashed", color = "black", linewidth = 1, alpha = 0.8) +
  geom_vline(xintercept = as.Date("2025-06-09"), linetype = "dashed", color = "black", linewidth = 1, alpha = 0.8) +
  # Points de données de température
  geom_point(color = "maroon3") +
  # Multiples courbes de lissage avec différents niveaux de confiance
  geom_smooth(se = TRUE, level = 0.1, alpha = 0.1, color = "maroon3") +
  geom_smooth(se = TRUE, level = 0.2, alpha = 0.1, color = "maroon3") +
  geom_smooth(se = TRUE, level = 0.3, alpha = 0.1, color = "maroon3") +
  geom_smooth(se = TRUE, level = 0.4, alpha = 0.1, color = "maroon3") +
  geom_smooth(se = TRUE, level = 0.5, alpha = 0.1, color = "maroon3") +
  geom_smooth(se = TRUE, level = 0.6, alpha = 0.1, color = "maroon3") +
  geom_smooth(se = TRUE, level = 0.7, alpha = 0.1, color = "maroon3") +
  geom_smooth(se = TRUE, level = 0.8, alpha = 0.1, color = "maroon3") +
  geom_smooth(se = TRUE, level = 0.9, alpha = 0.075, color = "maroon3") +
  geom_smooth(se = TRUE, level = 0.95, alpha = 0.05, linewidth = 2, color = "maroon3") +
  # Annotations pour les dates d'activités d'échantillonnage
  annotate("text", 
            x = as.Date(c("2025-06-03", "2025-06-06", "2025-06-09")), 
            y = c(3.5,5,3.5), 
            label = c("pose des pièges", "changement de pièges & récoltes actives", "retrait des pièges"),
            size = 5) +
  labs(y = "Température (C)", x = NULL, title = "Profil de température lors de l'échantillonnage (Site 1)") +
  theme(
  axis.line = element_line(linewidth = 2, lineend = "round"),
  panel.grid = element_blank(),
  panel.background = element_blank(),
  axis.ticks = element_blank(),
  axis.text = element_text(size = 14, face = "bold"),
  axis.title = element_text(size = 16, face = "bold"),
  plot.title = element_text(size = 17, face = "bold"))
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
Figure 5: Profil de température pour le Site 1 (habitat forestier) pendant la période d’échantillonnage. Les lignes verticales indiquent les dates de collecte entomologique.

Éléments de visualisation avancée : - geom_vline() : Lignes verticales pour marquer les dates d’échantillonnage - geom_smooth() : Courbes de tendance avec intervalles de confiance multiples - annotate() : Annotations textuelles pour expliquer les dates importantes - theme() : Personnalisation complète de l’apparence du graphique

Courbes de lissage multiples : L’utilisation de plusieurs niveaux de confiance (0.1 à 0.95) crée un effet visuel dégradé qui montre l’incertitude autour de la tendance générale.

6.5 Étape 12: Visualisation des profils de précipitations

Les précipitations influencent fortement l’activité des insectes. Ce graphique nous permet d’identifier les périodes de pluie et leur impact potentiel sur nos captures.

# Graphique de précipitations pour le Site 1
ggplot(meteo_site_1, aes(x = DY_local, y = precip)) +
  # Lignes verticales pour marquer les dates importantes d'échantillonnage
  geom_vline(xintercept = as.Date("2025-06-03"), linetype = "dashed", color = "black", linewidth = 1, alpha = 0.8) +
  geom_vline(xintercept = as.Date("2025-06-06"), linetype = "dashed", color = "black", linewidth = 1, alpha = 0.8) +
  geom_vline(xintercept = as.Date("2025-06-09"), linetype = "dashed", color = "black", linewidth = 1, alpha = 0.8) +
  # Points de données de précipitations
  geom_point(color = "steelblue3") +
  # Multiples courbes de lissage avec différents niveaux de confiance
  geom_smooth(se = TRUE, level = 0.1, alpha = 0.1, color = "steelblue3") +
  geom_smooth(se = TRUE, level = 0.2, alpha = 0.1, color = "steelblue3") +
  geom_smooth(se = TRUE, level = 0.3, alpha = 0.1, color = "steelblue3") +
  geom_smooth(se = TRUE, level = 0.4, alpha = 0.1, color = "steelblue3") +
  geom_smooth(se = TRUE, level = 0.5, alpha = 0.1, color = "steelblue3") +
  geom_smooth(se = TRUE, level = 0.6, alpha = 0.1, color = "steelblue3") +
  geom_smooth(se = TRUE, level = 0.7, alpha = 0.1, color = "steelblue3") +
  geom_smooth(se = TRUE, level = 0.8, alpha = 0.1, color = "steelblue3") +
  geom_smooth(se = TRUE, level = 0.9, alpha = 0.075, color = "steelblue3") +
  geom_smooth(se = TRUE, level = 0.95, alpha = 0.05, linewidth = 2, color = "steelblue3") +
  # Annotations pour les dates d'activités d'échantillonnage
  annotate("text", 
            x = as.Date(c("2025-06-03", "2025-06-06", "2025-06-09")), 
            y = c(25,20,25), 
            label = c("pose des pièges", "changement de pièges & récoltes actives", "retrait des pièges"),
            size = 5) +
  labs(y = "Précipitation (mm)", x = NULL, title = "Profil de Précipitations lors de l'échantillonnage (Site 1)") +
  theme(
  axis.line = element_line(linewidth = 2, lineend = "round"),
  panel.grid = element_blank(),
  panel.background = element_blank(),
  axis.ticks = element_blank(),
  axis.text = element_text(size = 14, face = "bold"),
  axis.title = element_text(size = 16, face = "bold"),
  plot.title = element_text(size = 17, face = "bold"))
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
Figure 6: Profil de précipitations pour le Site 1 (habitat forestier) pendant la période d’échantillonnage. Les bandes de confiance multiples illustrent l’incertitude des tendances temporelles.

Couleurs différentielles : - Bleu (steelblue3) pour les précipitations (association intuitive avec l’eau) - Rouge (maroon3) pour la température (association avec la chaleur)

Cette différenciation visuelle facilite l’interprétation rapide des graphiques.

6.6 Étape 13: Données météorologiques pour le Site 2

Pour une analyse comparative complète, nous répétons le même processus pour le Site 2. Cette approche nous permettra de comparer les conditions météorologiques entre les deux habitats (forestier vs ouvert).

6.7 Site 2

# Extraction de la latitude unique pour le site 2
lat_2 <- pieges |>
  filter(type_de_piege == "malaise") |>
  filter(site == 2) |>
  st_coordinates() |>
  as_tibble() |>
  pull(Y) |>
  unique()

# Extraction de la longitude unique pour le site 2  
lon_2 <- pieges |>
  filter(type_de_piege == "malaise") |>
  filter(site == 2) |>
  st_coordinates() |>
  as_tibble() |>
  pull(X) |>
  unique()

# Affichage des coordonnées extraites pour vérification
print(paste("Latitude (Y):", lat_2))
[1] "Latitude (Y): 45.3809505026146"
print(paste("Longitude (X):", lon_2))
[1] "Longitude (X): -71.9109862927272"
# Note: get_power() attend lonlat = c(longitude, latitude)
meteo_site_2 <- get_power(community = "ag",
                          temporal_api = "hourly",
                          lonlat = c(lon_2, lat_2),  # longitude d'abord, puis latitude
                          dates = c("2025-06-02", "2025-06-11"),
                          pars = c("TS", "PRECTOTCORR"))

glimpse(meteo_site_2)
Rows: 240
Columns: 8
$ LON         <dbl> -71.91099, -71.91099, -71.91099, -71.91099, -71.91099, -71…
$ LAT         <dbl> 45.38095, 45.38095, 45.38095, 45.38095, 45.38095, 45.38095…
$ YEAR        <dbl> 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025…
$ MO          <dbl> 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6…
$ DY          <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2…
$ HR          <dbl> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, …
$ TS          <dbl> 6.73, 6.68, 6.62, 6.61, 6.69, 7.05, 7.70, 9.09, 11.67, 13.…
$ PRECTOTCORR <dbl> 0.95, 0.79, 0.66, 0.43, 0.21, 0.10, 0.05, 0.02, 0.01, 0.01…

Importance de la réplication : En analysant les deux sites avec la même méthodologie, nous pouvons : 1. Comparer les microclimats entre habitats 2. Identifier les différences météorologiques qui pourraient expliquer les variations dans les communautés d’insectes 3. Valider la cohérence de nos méthodes d’analyse

6.8 Étape 14: Traitement des données météorologiques du Site 2

Nous appliquons la même séquence de conversion de fuseau horaire et de nettoyage des données pour assurer la cohérence entre les sites.

# Conversion du temps UTC vers UTC-4 pour le Site 2
# Débogage des données originales
print("Structure des données originales:")
[1] "Structure des données originales:"
print(str(meteo_site_2$DY))
 num [1:240] 2 2 2 2 2 2 2 2 2 2 ...
NULL
print(str(meteo_site_2$HR))
 num [1:240] 0 1 2 3 4 5 6 7 8 9 ...
NULL
print("Valeurs échantillons DY:")
[1] "Valeurs échantillons DY:"
print(head(meteo_site_2$DY))
[1] 2 2 2 2 2 2
print("Valeurs échantillons HR:")
[1] "Valeurs échantillons HR:"
print(head(meteo_site_2$HR))
[1] 0 1 2 3 4 5
meteo_site_2 <- meteo_site_2 |>
  mutate(
    # Débogage: vérification de l'opération de collage
    datetime_string = paste(DY, sprintf("%02d:00:00", HR)),
    
    # Utilisation des colonnes YEAR et MO réelles des données NASA POWER
    datetime_utc = ISOdate(year = YEAR, 
                          month = MO, 
                          day = DY, 
                          hour = HR, 
                          min = 0, 
                          sec = 0, 
                          tz = "UTC"),
    
    # Conversion vers UTC-4 (heure avancée de l'Est) - soustraction de 4 heures en secondes
    datetime_local = datetime_utc - (4 * 3600),
    
    # Extraction du jour et de l'heure locaux
    DY_local = as.Date(datetime_local),
    HR_local = as.numeric(format(datetime_local, "%H"))
  )

# Affichage des données converties
print("Après conversion:")
[1] "Après conversion:"
print("Échantillons datetime_string:")
[1] "Échantillons datetime_string:"
print(head(meteo_site_2$datetime_string))
[1] "2 00:00:00" "2 01:00:00" "2 02:00:00" "2 03:00:00" "2 04:00:00"
[6] "2 05:00:00"
print("Échantillons datetime_utc:")
[1] "Échantillons datetime_utc:"
print(head(meteo_site_2$datetime_utc))
[1] "2025-06-02 00:00:00 UTC" "2025-06-02 01:00:00 UTC"
[3] "2025-06-02 02:00:00 UTC" "2025-06-02 03:00:00 UTC"
[5] "2025-06-02 04:00:00 UTC" "2025-06-02 05:00:00 UTC"
print("Échantillons datetime_local:")
[1] "Échantillons datetime_local:"
print(head(meteo_site_2$datetime_local))
[1] "2025-06-01 20:00:00 UTC" "2025-06-01 21:00:00 UTC"
[3] "2025-06-01 22:00:00 UTC" "2025-06-01 23:00:00 UTC"
[5] "2025-06-02 00:00:00 UTC" "2025-06-02 01:00:00 UTC"
glimpse(meteo_site_2)
Rows: 240
Columns: 13
$ LON             <dbl> -71.91099, -71.91099, -71.91099, -71.91099, -71.91099,…
$ LAT             <dbl> 45.38095, 45.38095, 45.38095, 45.38095, 45.38095, 45.3…
$ YEAR            <dbl> 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, …
$ MO              <dbl> 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, …
$ DY              <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, …
$ HR              <dbl> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, …
$ TS              <dbl> 6.73, 6.68, 6.62, 6.61, 6.69, 7.05, 7.70, 9.09, 11.67,…
$ PRECTOTCORR     <dbl> 0.95, 0.79, 0.66, 0.43, 0.21, 0.10, 0.05, 0.02, 0.01, …
$ datetime_string <chr> "2 00:00:00", "2 01:00:00", "2 02:00:00", "2 03:00:00"…
$ datetime_utc    <dttm> 2025-06-02 00:00:00, 2025-06-02 01:00:00, 2025-06-02 …
$ datetime_local  <dttm> 2025-06-01 20:00:00, 2025-06-01 21:00:00, 2025-06-01 …
$ DY_local        <date> 2025-06-01, 2025-06-01, 2025-06-01, 2025-06-01, 2025-…
$ HR_local        <dbl> 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, …

Standardisation des procédures : En utilisant exactement la même séquence de code pour les deux sites, nous évitons les erreurs de traitement et garantissons que toute différence observée reflète de vraies différences environnementales, non des artéfacts de traitement des données.

6.9 Étape 15: Préparation finale des données du Site 2

# Nettoyage et renommage des données météorologiques du Site 2
meteo_site_2 <- meteo_site_2 |>
                 rename(temp = TS,              # Température
                        precip = PRECTOTCORR) |> # Précipitations corrigées
                 select(DY_local, HR_local, temp, precip)

Cette étape finalise la préparation de nos données pour les visualisations comparatives entre les deux sites.

6.10 Étape 16: Visualisations comparatives pour le Site 2

Les graphiques du Site 2 nous permettront de comparer les profils météorologiques entre l’habitat forestier (Site 1) et l’habitat ouvert (Site 2).

# Graphique de température pour le Site 2
ggplot(meteo_site_2, aes(x = DY_local, y = temp)) +
  # Lignes verticales pour marquer les dates importantes d'échantillonnage
  geom_vline(xintercept = as.Date("2025-06-03"), linetype = "dashed", color = "black", linewidth = 1, alpha = 0.8) +
  geom_vline(xintercept = as.Date("2025-06-06"), linetype = "dashed", color = "black", linewidth = 1, alpha = 0.8) +
  geom_vline(xintercept = as.Date("2025-06-09"), linetype = "dashed", color = "black", linewidth = 1, alpha = 0.8) +
  # Points de données de température
  geom_point(color = "maroon3") +
  # Multiples courbes de lissage avec différents niveaux de confiance
  geom_smooth(se = TRUE, level = 0.1, alpha = 0.1, color = "maroon3") +
  geom_smooth(se = TRUE, level = 0.2, alpha = 0.1, color = "maroon3") +
  geom_smooth(se = TRUE, level = 0.3, alpha = 0.1, color = "maroon3") +
  geom_smooth(se = TRUE, level = 0.4, alpha = 0.1, color = "maroon3") +
  geom_smooth(se = TRUE, level = 0.5, alpha = 0.1, color = "maroon3") +
  geom_smooth(se = TRUE, level = 0.6, alpha = 0.1, color = "maroon3") +
  geom_smooth(se = TRUE, level = 0.7, alpha = 0.1, color = "maroon3") +
  geom_smooth(se = TRUE, level = 0.8, alpha = 0.1, color = "maroon3") +
  geom_smooth(se = TRUE, level = 0.9, alpha = 0.075, color = "maroon3") +
  geom_smooth(se = TRUE, level = 0.95, alpha = 0.05, linewidth = 2, color = "maroon3") +
  # Annotations pour les dates d'activités d'échantillonnage
  annotate("text", 
            x = as.Date(c("2025-06-03", "2025-06-06", "2025-06-09")), 
            y = c(3.5,5,3.5), 
            label = c("pose des pièges", "changement de pièges & récoltes actives", "retrait des pièges"),
            size = 5) +
  labs(y = "Température (C)", x = NULL, title = "Profil de température lors de l'échantillonnage (Site 2)") +
  theme(
  axis.line = element_line(linewidth = 2, lineend = "round"),
  panel.grid = element_blank(),
  panel.background = element_blank(),
  axis.ticks = element_blank(),
  axis.text = element_text(size = 14, face = "bold"),
  axis.title = element_text(size = 16, face = "bold"),
  plot.title = element_text(size = 17, face = "bold"))
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
Figure 7: Profil de température pour le Site 2 (habitat ouvert) pendant la période d’échantillonnage. Comparaison avec le Site 1 pour analyser les différences d’habitat.

Nasapower modélise les variables météorologiques sur une grille avec cases de 50 x 50 km donc il se peut que les mesures soient identiques entre les sites.

6.11 Étape 17: Analyse finale des précipitations du Site 2

# Graphique de précipitations pour le Site 2
ggplot(meteo_site_2, aes(x = DY_local, y = precip)) +
  # Lignes verticales pour marquer les dates importantes d'échantillonnage
  geom_vline(xintercept = as.Date("2025-06-03"), linetype = "dashed", color = "black", linewidth = 1, alpha = 0.8) +
  geom_vline(xintercept = as.Date("2025-06-06"), linetype = "dashed", color = "black", linewidth = 1, alpha = 0.8) +
  geom_vline(xintercept = as.Date("2025-06-09"), linetype = "dashed", color = "black", linewidth = 1, alpha = 0.8) +
  # Points de données de précipitations
  geom_point(color = "steelblue3") +
  # Multiples courbes de lissage avec différents niveaux de confiance
  geom_smooth(se = TRUE, level = 0.1, alpha = 0.1, color = "steelblue3") +
  geom_smooth(se = TRUE, level = 0.2, alpha = 0.1, color = "steelblue3") +
  geom_smooth(se = TRUE, level = 0.3, alpha = 0.1, color = "steelblue3") +
  geom_smooth(se = TRUE, level = 0.4, alpha = 0.1, color = "steelblue3") +
  geom_smooth(se = TRUE, level = 0.5, alpha = 0.1, color = "steelblue3") +
  geom_smooth(se = TRUE, level = 0.6, alpha = 0.1, color = "steelblue3") +
  geom_smooth(se = TRUE, level = 0.7, alpha = 0.1, color = "steelblue3") +
  geom_smooth(se = TRUE, level = 0.8, alpha = 0.1, color = "steelblue3") +
  geom_smooth(se = TRUE, level = 0.9, alpha = 0.075, color = "steelblue3") +
  geom_smooth(se = TRUE, level = 0.95, alpha = 0.05, linewidth = 2, color = "steelblue3") +
  # Annotations pour les dates d'activités d'échantillonnage
  annotate("text", 
            x = as.Date(c("2025-06-03", "2025-06-06", "2025-06-09")), 
            y = c(25,20,25), 
            label = c("pose des pièges", "changement de pièges & récoltes actives", "retrait des pièges"),
            size = 5) +
  labs(y = "Précipitation (mm)", x = NULL, title = "Profil de Précipitations lors de l'échantillonnage (Site 2)") +
  theme(
  axis.line = element_line(linewidth = 2, lineend = "round"),
  panel.grid = element_blank(),
  panel.background = element_blank(),
  axis.ticks = element_blank(),
  axis.text = element_text(size = 14, face = "bold"),
  axis.title = element_text(size = 16, face = "bold"),
  plot.title = element_text(size = 17, face = "bold"))
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
Figure 8: Profil de précipitations pour le Site 2 (habitat ouvert) pendant la période d’échantillonnage. Les bandes de confiance multiples illustrent l’incertitude des tendances temporelles.

7 Intégration et traitement des données biologiques

7.1 Étape 18: Intégration des données d’identification d’insectes

Maintenant que nous avons analysé les conditions spatiales et météorologiques, nous devons intégrer les données d’identification des insectes capturés. Cette étape nécessite d’harmoniser les identifiants d’échantillons et d’extraire les coordonnées géographiques pour chaque échantillon.

data_insectes <- read_excel("echantillons_campus_2025_exemple.xlsx")
New names:
• `` -> `...30`
• `` -> `...31`
• `` -> `...32`
• `` -> `...33`
• `` -> `...34`
glimpse(data_insectes)
Rows: 6
Columns: 34
$ echantillon_ID             <chr> "FF_6_1", "FF_6_2", "BJaune_6_1", "BJaune_6…
$ Plecoptera                 <dbl> 0, 0, 0, 0, 0, 0
$ Dermaptera                 <dbl> 0, 0, 0, 0, 0, 0
$ `Orthoptera (Caelifères)`  <dbl> 9, 0, 0, 0, 0, 0
$ `Orthoptera (Ensifères)`   <dbl> 1, 0, 0, 0, 0, 0
$ Phasmatodea                <dbl> 0, 0, 0, 0, 0, 0
$ Mantodea                   <dbl> 0, 0, 0, 0, 0, 0
$ Blattodea                  <dbl> 0, 0, 0, 0, 0, 0
$ `Psocodea (phthiraptera)`  <dbl> 0, 0, 0, 0, 0, 0
$ `Psocodea (psocoptera)`    <dbl> 0, 0, 0, 0, 9, 10
$ Thysanoptera               <dbl> 0, 1, 0, 0, 0, 0
$ `Hemiptera (Homoptères)`   <dbl> 2, 19, 3, 0, 0, 3
$ `Hemiptera (Hétéroptères)` <dbl> 40, 14, 0, 0, 1, 8
$ Raphidioptera              <dbl> 0, 0, 0, 0, 0, 0
$ Megaloptera                <dbl> 0, 0, 0, 0, 0, 0
$ Neuroptera                 <dbl> 0, 0, 0, 0, 0, 0
$ `Coléoptères (Apéphages)`  <dbl> 0, 0, 0, 0, 0, 0
$ `Coléoptères (Polyphages)` <dbl> 2, 0, 1, 1, 0, 0
$ Strepsiptera               <dbl> 0, 0, 0, 0, 0, 0
$ `Diptères (Nématocères)`   <dbl> 0, 3, 4, 2, 7, 5
$ `Diptères (Brachycères)`   <dbl> 3, 4, 10, 19, 0, 0
$ Mecoptera                  <dbl> 0, 0, 0, 0, 0, 0
$ Siphonaptera               <dbl> 0, 0, 0, 0, 0, 0
$ Trichoptera                <dbl> 0, 0, 0, 0, 0, 0
$ Lepidoptera                <dbl> 0, 0, 0, 0, 2, 2
$ `Hymenoptera (Symphytes)`  <dbl> 0, 0, 0, 0, 0, 0
$ `Hymenoptera (Apocrites)`  <dbl> 7, 5, 9, 1, 1, 2
$ Araignées                  <dbl> 0, 0, 0, 0, 0, 1
$ Myriapodes                 <dbl> 0, 0, 0, 0, 0, 0
$ ...30                      <dbl> 0, NA, NA, NA, NA, NA
$ ...31                      <dbl> 0, NA, NA, NA, NA, NA
$ ...32                      <dbl> 0, NA, NA, NA, NA, NA
$ ...33                      <dbl> 0, NA, NA, NA, NA, NA
$ ...34                      <dbl> 0, NA, NA, NA, NA, NA
glimpse(pieges)
Rows: 4
Columns: 41
$ type_de_piege                        <chr> "Bol_jaune", "Bol_jaune", "malais…
$ date_pose                            <dttm> 2025-06-29 12:45:00, 2025-06-29 …
$ date_recolte                         <dttm> 2025-07-01 13:00:00, 2025-07-05 …
$ date_retrait                         <dttm> 2025-07-05 13:39:28, 2025-07-05 …
$ couverture_arborescente              <int> 0, 80, 75, 20
$ couverture_arbustive                 <int> 45, 45, 50, 31
$ couverture_herbacee                  <int> 85, 30, 65, 90
$ espece_dominante_strate_arbustive    <chr> NA, NA, NA, NA
$ espece_dominante_strate_arborescente <chr> NA, NA, NA, NA
$ espece_dominante_strate_herbacee     <chr> NA, NA, NA, NA
$ type_de_sol                          <chr> NA, NA, NA, NA
$ pente                                <int> NA, NA, NA, NA
$ autre_commentaire                    <chr> NA, NA, NA, NA
$ piege_ID                             <chr> "BJaune_6_2", "BJaune_6_1", "M_1_…
$ geometry                             <POINT [°]> POINT (-71.91162 45.38107), POINT…
$ site                                 <dbl> 2, 1, 1, 2
$ type_habitat                         <chr> "Ouvert", "Forestier", "Forestier…
$ date_pose_parsed                     <dttm> 2025-06-29 12:45:00, 2025-06-29 1…
$ date_pose_date                       <date> 2025-06-29, 2025-06-29, 2025-06-2…
$ date_pose_time                       <time> 12:45:00.000, 12:45:00.587, 12:45…
$ date_pose_year                       <dbl> 2025, 2025, 2025, 2025
$ date_pose_month                      <dbl> 6, 6, 6, 6
$ date_pose_day                        <int> 29, 29, 29, 29
$ date_pose_hour                       <int> 12, 12, 12, 12
$ date_pose_minute                     <int> 45, 45, 45, 45
$ date_recolte_parsed                  <dttm> 2025-07-01 13:00:00, 2025-07-05 1…
$ date_recolte_date                    <date> 2025-07-01, 2025-07-05, 2025-07-0…
$ date_recolte_time                    <time> 13:00:00.000, 13:00:00.016, 13:00…
$ date_recolte_year                    <dbl> 2025, 2025, 2025, 2025
$ date_recolte_month                   <dbl> 7, 7, 7, 7
$ date_recolte_day                     <int> 1, 5, 1, 1
$ date_recolte_hour                    <int> 13, 13, 13, 13
$ date_recolte_minute                  <int> 0, 0, 0, 0
$ date_retrait_parsed                  <dttm> 2025-07-05 13:39:28, 2025-07-05 1…
$ date_retrait_date                    <date> 2025-07-05, 2025-07-05, 202…
$ date_retrait_time                    <time> 13:39:28.509001, 13:39:33.799999,…
$ date_retrait_year                    <dbl> 2025, 2025, 2025, 2025
$ date_retrait_month                   <dbl> 7, 7, 7, 7
$ date_retrait_day                     <int> 5, 5, 5, 5
$ date_retrait_hour                    <int> 13, 13, 13, 13
$ date_retrait_minute                  <int> 39, 39, 39, 39
glimpse(recoltes_actives)
Rows: 2
Columns: 14
$ date_heure                    <dttm> 2025-07-05 12:53:34, 2025-07-05 13:35:41
$ type_recolte                  <chr> "filet_fauchoir", "filet_fauchoir"
$ couverture_arborescente       <int> 80, 0
$ couverture_arbustive          <int> 50, 20
$ couverture_herbacee           <int> 76, 90
$ espece_dominante_arborescente <chr> NA, NA
$ espece_dominante_arbustive    <chr> NA, NA
$ espece_dominante_herbacee     <chr> NA, NA
$ type_sol                      <chr> NA, NA
$ pente                         <int> NA, NA
$ autre_commentaire             <chr> NA, NA
$ ID_echantillon                <chr> "FF_6_1", "FF_6_2"
$ geometry                      <LINESTRING [°]> LINESTRING M (-71.90842 45...., LINESTR…
$ site                          <dbl> 1, 2

Nous voulons joindre l’identifiant du site des données de pièges et récoltes actives à la base de données d’insectes.

La colonne identifiant les échantillons dans data_insectes s’appelle echantillon_ID tandis que dans la base de données des pièges, elle s’appelle piege_ID et ID_echantillon dans la base de données des récoltes actives. Nous allons homogénéiser les noms de colonnes pour pouvoir joindre les données ensemble. Nous allons aussi joindre les données de latitude et longitude des données géoréférencées.

7.2 Étape 19: Extraction des coordonnées géographiques

Pour chaque échantillon, nous devons extraire les coordonnées géographiques. Pour les pièges (points), nous extrayons directement les coordonnées. Pour les récoltes actives (lignes), nous calculons le centroïde de chaque transect.

pieges <- pieges |>
            mutate(echantillon_ID = piege_ID)

recoltes_actives <- recoltes_actives |>
            mutate(echantillon_ID = ID_echantillon)

# Extraction des coordonnées X & Y pour les pièges (points)
pieges_coords <- pieges |>
  st_coordinates() |>
  as_tibble() |>
  rename(longitude = X, latitude = Y)

# Ajout des coordonnées aux données de pièges
pieges <- pieges |>
  bind_cols(pieges_coords)

# Extraction des coordonnées X & Y pour les récoltes actives (centroïdes des lignes)
recoltes_coords <- recoltes_actives |>
  st_centroid() |>  # Calcul du centroïde de chaque ligne
  st_coordinates() |>
  as_tibble() |>
  rename(longitude = X, latitude = Y)
Warning: st_centroid assumes attributes are constant over geometries
st_as_s2(): dropping Z and/or M coordinate
# Ajout des coordonnées aux données de récoltes actives
recoltes_actives <- recoltes_actives |>
  bind_cols(recoltes_coords)

# Vérification des coordonnées extraites
glimpse(pieges |> st_drop_geometry() |> select(echantillon_ID, longitude, latitude))
Rows: 4
Columns: 3
$ echantillon_ID <chr> "BJaune_6_2", "BJaune_6_1", "M_1_1_6", "M_2_1_6"
$ longitude      <dbl> -71.91162, -71.90792, -71.90850, -71.91099
$ latitude       <dbl> 45.38107, 45.38162, 45.38122, 45.38095
glimpse(recoltes_actives |> st_drop_geometry() |> select(echantillon_ID, longitude, latitude))
Rows: 2
Columns: 3
$ echantillon_ID <chr> "FF_6_1", "FF_6_2"
$ longitude      <dbl> -71.90810, -71.91132
$ latitude       <dbl> 45.38143, 45.38102

Fonctions utilisées pour l’extraction de coordonnées : - st_coordinates() : Extrait les coordonnées X,Y des objets spatiaux - st_centroid() : Calcule le centroïde (point central) d’une géométrie - bind_cols() : Ajoute les colonnes de coordonnées aux données originales

Pourquoi utiliser les centroïdes pour les lignes ? Les récoltes actives sont des transects linéaires. Le centroïde nous donne un point représentatif de la position centrale de chaque transect, ce qui permet d’assigner une coordonnée unique à chaque échantillon de récolte active.

7.3 Étape 20: Jointure des données spatiales avec les données d’insectes

Maintenant nous devons joindre les informations de localisation (latitude, longitude, site) des pièges et récoltes actives avec les données d’identification d’insectes.

# Préparation des données spatiales pour la jointure
# Sélection des colonnes pertinentes des pièges
pieges_spatial <- pieges |>
  st_drop_geometry() |>
  select(echantillon_ID, longitude, latitude, site)

# Sélection des colonnes pertinentes des récoltes actives
recoltes_spatial <- recoltes_actives |>
  st_drop_geometry() |>
  select(echantillon_ID, longitude, latitude, site)

# Combinaison des données spatiales des deux méthodes d'échantillonnage
spatial_data <- bind_rows(pieges_spatial, recoltes_spatial)

# Jointure avec les données d'insectes
data_insectes_complete <- data_insectes |>
  left_join(spatial_data, by = "echantillon_ID")

# Vérification du résultat
glimpse(data_insectes_complete)
Rows: 6
Columns: 37
$ echantillon_ID             <chr> "FF_6_1", "FF_6_2", "BJaune_6_1", "BJaune_6…
$ Plecoptera                 <dbl> 0, 0, 0, 0, 0, 0
$ Dermaptera                 <dbl> 0, 0, 0, 0, 0, 0
$ `Orthoptera (Caelifères)`  <dbl> 9, 0, 0, 0, 0, 0
$ `Orthoptera (Ensifères)`   <dbl> 1, 0, 0, 0, 0, 0
$ Phasmatodea                <dbl> 0, 0, 0, 0, 0, 0
$ Mantodea                   <dbl> 0, 0, 0, 0, 0, 0
$ Blattodea                  <dbl> 0, 0, 0, 0, 0, 0
$ `Psocodea (phthiraptera)`  <dbl> 0, 0, 0, 0, 0, 0
$ `Psocodea (psocoptera)`    <dbl> 0, 0, 0, 0, 9, 10
$ Thysanoptera               <dbl> 0, 1, 0, 0, 0, 0
$ `Hemiptera (Homoptères)`   <dbl> 2, 19, 3, 0, 0, 3
$ `Hemiptera (Hétéroptères)` <dbl> 40, 14, 0, 0, 1, 8
$ Raphidioptera              <dbl> 0, 0, 0, 0, 0, 0
$ Megaloptera                <dbl> 0, 0, 0, 0, 0, 0
$ Neuroptera                 <dbl> 0, 0, 0, 0, 0, 0
$ `Coléoptères (Apéphages)`  <dbl> 0, 0, 0, 0, 0, 0
$ `Coléoptères (Polyphages)` <dbl> 2, 0, 1, 1, 0, 0
$ Strepsiptera               <dbl> 0, 0, 0, 0, 0, 0
$ `Diptères (Nématocères)`   <dbl> 0, 3, 4, 2, 7, 5
$ `Diptères (Brachycères)`   <dbl> 3, 4, 10, 19, 0, 0
$ Mecoptera                  <dbl> 0, 0, 0, 0, 0, 0
$ Siphonaptera               <dbl> 0, 0, 0, 0, 0, 0
$ Trichoptera                <dbl> 0, 0, 0, 0, 0, 0
$ Lepidoptera                <dbl> 0, 0, 0, 0, 2, 2
$ `Hymenoptera (Symphytes)`  <dbl> 0, 0, 0, 0, 0, 0
$ `Hymenoptera (Apocrites)`  <dbl> 7, 5, 9, 1, 1, 2
$ Araignées                  <dbl> 0, 0, 0, 0, 0, 1
$ Myriapodes                 <dbl> 0, 0, 0, 0, 0, 0
$ ...30                      <dbl> 0, NA, NA, NA, NA, NA
$ ...31                      <dbl> 0, NA, NA, NA, NA, NA
$ ...32                      <dbl> 0, NA, NA, NA, NA, NA
$ ...33                      <dbl> 0, NA, NA, NA, NA, NA
$ ...34                      <dbl> 0, NA, NA, NA, NA, NA
$ longitude                  <dbl> -71.90810, -71.91132, -71.90792, -71.91162,…
$ latitude                   <dbl> 45.38143, 45.38102, 45.38162, 45.38107, 45.…
$ site                       <dbl> 1, 2, 1, 2, 1, 2
# Affichage des premières lignes pour vérifier la jointure
head(data_insectes_complete)
# A tibble: 6 × 37
  echantillon_ID Plecoptera Dermaptera `Orthoptera (Caelifères)`
  <chr>               <dbl>      <dbl>                     <dbl>
1 FF_6_1                  0          0                         9
2 FF_6_2                  0          0                         0
3 BJaune_6_1              0          0                         0
4 BJaune_6_2              0          0                         0
5 M_1_1_6                 0          0                         0
6 M_2_1_6                 0          0                         0
# ℹ 33 more variables: `Orthoptera (Ensifères)` <dbl>, Phasmatodea <dbl>,
#   Mantodea <dbl>, Blattodea <dbl>, `Psocodea (phthiraptera)` <dbl>,
#   `Psocodea (psocoptera)` <dbl>, Thysanoptera <dbl>,
#   `Hemiptera (Homoptères)` <dbl>, `Hemiptera (Hétéroptères)` <dbl>,
#   Raphidioptera <dbl>, Megaloptera <dbl>, Neuroptera <dbl>,
#   `Coléoptères (Apéphages)` <dbl>, `Coléoptères (Polyphages)` <dbl>,
#   Strepsiptera <dbl>, `Diptères (Nématocères)` <dbl>, …

Fonctions utilisées pour la jointure : - bind_rows() : Combine verticalement les données de pièges et récoltes actives - left_join() : Joint les données en gardant tous les échantillons d’insectes - by = "echantillon_ID" : Spécifie la colonne commune pour la jointure

Résultat de la jointure : Chaque insecte identifié est maintenant associé à : - Sa latitude et longitude précises - Son site d’appartenance (1 = forestier, 2 = ouvert) - Toutes les informations taxonomiques originales

7.4 Étape 21: Nettoyage des noms de colonnes

Les noms de colonnes dans les données d’insectes contiennent souvent des caractères problématiques (espaces, accents, caractères spéciaux) qui compliquent la programmation en R. Nous allons utiliser la fonction clean_names() du package janitor pour standardiser ces noms.

# Examen des noms de colonnes problématiques
print("Noms de colonnes avant nettoyage:")
[1] "Noms de colonnes avant nettoyage:"
print(names(data_insectes_complete))
 [1] "echantillon_ID"           "Plecoptera"              
 [3] "Dermaptera"               "Orthoptera (Caelifères)" 
 [5] "Orthoptera (Ensifères)"   "Phasmatodea"             
 [7] "Mantodea"                 "Blattodea"               
 [9] "Psocodea (phthiraptera)"  "Psocodea (psocoptera)"   
[11] "Thysanoptera"             "Hemiptera (Homoptères)"  
[13] "Hemiptera (Hétéroptères)" "Raphidioptera"           
[15] "Megaloptera"              "Neuroptera"              
[17] "Coléoptères (Apéphages)"  "Coléoptères (Polyphages)"
[19] "Strepsiptera"             "Diptères (Nématocères)"  
[21] "Diptères (Brachycères)"   "Mecoptera"               
[23] "Siphonaptera"             "Trichoptera"             
[25] "Lepidoptera"              "Hymenoptera (Symphytes)" 
[27] "Hymenoptera (Apocrites)"  "Araignées"               
[29] "Myriapodes"               "...30"                   
[31] "...31"                    "...32"                   
[33] "...33"                    "...34"                   
[35] "longitude"                "latitude"                
[37] "site"                    
# Nettoyage des noms de colonnes avec janitor
data_insectes_clean <- data_insectes_complete |>
  clean_names()

# Vérification des noms de colonnes après nettoyage
print("Noms de colonnes après nettoyage:")
[1] "Noms de colonnes après nettoyage:"
print(names(data_insectes_clean))
 [1] "echantillon_id"         "plecoptera"             "dermaptera"            
 [4] "orthoptera_caeliferes"  "orthoptera_ensiferes"   "phasmatodea"           
 [7] "mantodea"               "blattodea"              "psocodea_phthiraptera" 
[10] "psocodea_psocoptera"    "thysanoptera"           "hemiptera_homopteres"  
[13] "hemiptera_heteropteres" "raphidioptera"          "megaloptera"           
[16] "neuroptera"             "coleopteres_apephages"  "coleopteres_polyphages"
[19] "strepsiptera"           "dipteres_nematoceres"   "dipteres_brachyceres"  
[22] "mecoptera"              "siphonaptera"           "trichoptera"           
[25] "lepidoptera"            "hymenoptera_symphytes"  "hymenoptera_apocrites" 
[28] "araignees"              "myriapodes"             "x30"                   
[31] "x31"                    "x32"                    "x33"                   
[34] "x34"                    "longitude"              "latitude"              
[37] "site"                  
# Comparaison côte à côte pour voir les changements
comparison <- data.frame(
  avant = names(data_insectes_complete),
  apres = names(data_insectes_clean)
)
print("Comparaison des noms de colonnes:")
[1] "Comparaison des noms de colonnes:"
print(comparison)
                      avant                  apres
1            echantillon_ID         echantillon_id
2                Plecoptera             plecoptera
3                Dermaptera             dermaptera
4   Orthoptera (Caelifères)  orthoptera_caeliferes
5    Orthoptera (Ensifères)   orthoptera_ensiferes
6               Phasmatodea            phasmatodea
7                  Mantodea               mantodea
8                 Blattodea              blattodea
9   Psocodea (phthiraptera)  psocodea_phthiraptera
10    Psocodea (psocoptera)    psocodea_psocoptera
11             Thysanoptera           thysanoptera
12   Hemiptera (Homoptères)   hemiptera_homopteres
13 Hemiptera (Hétéroptères) hemiptera_heteropteres
14            Raphidioptera          raphidioptera
15              Megaloptera            megaloptera
16               Neuroptera             neuroptera
17  Coléoptères (Apéphages)  coleopteres_apephages
18 Coléoptères (Polyphages) coleopteres_polyphages
19             Strepsiptera           strepsiptera
20   Diptères (Nématocères)   dipteres_nematoceres
21   Diptères (Brachycères)   dipteres_brachyceres
22                Mecoptera              mecoptera
23             Siphonaptera           siphonaptera
24              Trichoptera            trichoptera
25              Lepidoptera            lepidoptera
26  Hymenoptera (Symphytes)  hymenoptera_symphytes
27  Hymenoptera (Apocrites)  hymenoptera_apocrites
28                Araignées              araignees
29               Myriapodes             myriapodes
30                    ...30                    x30
31                    ...31                    x31
32                    ...32                    x32
33                    ...33                    x33
34                    ...34                    x34
35                longitude              longitude
36                 latitude               latitude
37                     site                   site
# Vérification de la structure finale
glimpse(data_insectes_clean)
Rows: 6
Columns: 37
$ echantillon_id         <chr> "FF_6_1", "FF_6_2", "BJaune_6_1", "BJaune_6_2",…
$ plecoptera             <dbl> 0, 0, 0, 0, 0, 0
$ dermaptera             <dbl> 0, 0, 0, 0, 0, 0
$ orthoptera_caeliferes  <dbl> 9, 0, 0, 0, 0, 0
$ orthoptera_ensiferes   <dbl> 1, 0, 0, 0, 0, 0
$ phasmatodea            <dbl> 0, 0, 0, 0, 0, 0
$ mantodea               <dbl> 0, 0, 0, 0, 0, 0
$ blattodea              <dbl> 0, 0, 0, 0, 0, 0
$ psocodea_phthiraptera  <dbl> 0, 0, 0, 0, 0, 0
$ psocodea_psocoptera    <dbl> 0, 0, 0, 0, 9, 10
$ thysanoptera           <dbl> 0, 1, 0, 0, 0, 0
$ hemiptera_homopteres   <dbl> 2, 19, 3, 0, 0, 3
$ hemiptera_heteropteres <dbl> 40, 14, 0, 0, 1, 8
$ raphidioptera          <dbl> 0, 0, 0, 0, 0, 0
$ megaloptera            <dbl> 0, 0, 0, 0, 0, 0
$ neuroptera             <dbl> 0, 0, 0, 0, 0, 0
$ coleopteres_apephages  <dbl> 0, 0, 0, 0, 0, 0
$ coleopteres_polyphages <dbl> 2, 0, 1, 1, 0, 0
$ strepsiptera           <dbl> 0, 0, 0, 0, 0, 0
$ dipteres_nematoceres   <dbl> 0, 3, 4, 2, 7, 5
$ dipteres_brachyceres   <dbl> 3, 4, 10, 19, 0, 0
$ mecoptera              <dbl> 0, 0, 0, 0, 0, 0
$ siphonaptera           <dbl> 0, 0, 0, 0, 0, 0
$ trichoptera            <dbl> 0, 0, 0, 0, 0, 0
$ lepidoptera            <dbl> 0, 0, 0, 0, 2, 2
$ hymenoptera_symphytes  <dbl> 0, 0, 0, 0, 0, 0
$ hymenoptera_apocrites  <dbl> 7, 5, 9, 1, 1, 2
$ araignees              <dbl> 0, 0, 0, 0, 0, 1
$ myriapodes             <dbl> 0, 0, 0, 0, 0, 0
$ x30                    <dbl> 0, NA, NA, NA, NA, NA
$ x31                    <dbl> 0, NA, NA, NA, NA, NA
$ x32                    <dbl> 0, NA, NA, NA, NA, NA
$ x33                    <dbl> 0, NA, NA, NA, NA, NA
$ x34                    <dbl> 0, NA, NA, NA, NA, NA
$ longitude              <dbl> -71.90810, -71.91132, -71.90792, -71.91162, -71…
$ latitude               <dbl> 45.38143, 45.38102, 45.38162, 45.38107, 45.3812…
$ site                   <dbl> 1, 2, 1, 2, 1, 2

Avantages de clean_names() : - Supprime les espaces et les remplace par des underscores (_) - Supprime ou remplace les caractères spéciaux (parenthèses, crochets, etc.) - Normalise les accents (é devient e, à devient a, etc.) - Convertit tout en minuscules pour la cohérence - Assure que les noms sont valides pour R (pas de mots-clés réservés)

Pourquoi nettoyer les noms de colonnes ? Des noms de colonnes propres facilitent : - L’écriture de code (pas besoin de guillemets ou backticks) - L’auto-complétion dans RStudio - La lisibilité et la maintenance du code - L’évitement d’erreurs de syntaxe

# Inspection de quelques colonnes suspectes
# Vérifions si certaines colonnes sont vides ou remplies de NAs
data_insectes_clean |>
  select(x30, x31, x32, x33, x34) |>
  summary()
      x30         x31         x32         x33         x34   
 Min.   :0   Min.   :0   Min.   :0   Min.   :0   Min.   :0  
 1st Qu.:0   1st Qu.:0   1st Qu.:0   1st Qu.:0   1st Qu.:0  
 Median :0   Median :0   Median :0   Median :0   Median :0  
 Mean   :0   Mean   :0   Mean   :0   Mean   :0   Mean   :0  
 3rd Qu.:0   3rd Qu.:0   3rd Qu.:0   3rd Qu.:0   3rd Qu.:0  
 Max.   :0   Max.   :0   Max.   :0   Max.   :0   Max.   :0  
 NAs    :5   NAs    :5   NAs    :5   NAs    :5   NAs    :5  

Cette inspection nous révèle que les colonnes x30, x31, x32, x33, et x34 ne contiennent que des valeurs manquantes (NAs). Ces colonnes sont probablement des artefacts de l’importation des données Excel.

7.4.1 Suppression des colonnes inutiles

Il est important de supprimer les colonnes qui n’apportent aucune information pour : - Réduire la taille des données : moins de mémoire utilisée - Améliorer la lisibilité : se concentrer sur les données utiles - Éviter la confusion : éliminer les colonnes parasites - Optimiser les performances : calculs plus rapides

# Suppression des colonnes remplies de NAs
data_insectes_final <- data_insectes_clean |>
  select(-c(x30, x31, x32, x33, x34))

# Vérification de la structure finale
glimpse(data_insectes_final)
Rows: 6
Columns: 32
$ echantillon_id         <chr> "FF_6_1", "FF_6_2", "BJaune_6_1", "BJaune_6_2",…
$ plecoptera             <dbl> 0, 0, 0, 0, 0, 0
$ dermaptera             <dbl> 0, 0, 0, 0, 0, 0
$ orthoptera_caeliferes  <dbl> 9, 0, 0, 0, 0, 0
$ orthoptera_ensiferes   <dbl> 1, 0, 0, 0, 0, 0
$ phasmatodea            <dbl> 0, 0, 0, 0, 0, 0
$ mantodea               <dbl> 0, 0, 0, 0, 0, 0
$ blattodea              <dbl> 0, 0, 0, 0, 0, 0
$ psocodea_phthiraptera  <dbl> 0, 0, 0, 0, 0, 0
$ psocodea_psocoptera    <dbl> 0, 0, 0, 0, 9, 10
$ thysanoptera           <dbl> 0, 1, 0, 0, 0, 0
$ hemiptera_homopteres   <dbl> 2, 19, 3, 0, 0, 3
$ hemiptera_heteropteres <dbl> 40, 14, 0, 0, 1, 8
$ raphidioptera          <dbl> 0, 0, 0, 0, 0, 0
$ megaloptera            <dbl> 0, 0, 0, 0, 0, 0
$ neuroptera             <dbl> 0, 0, 0, 0, 0, 0
$ coleopteres_apephages  <dbl> 0, 0, 0, 0, 0, 0
$ coleopteres_polyphages <dbl> 2, 0, 1, 1, 0, 0
$ strepsiptera           <dbl> 0, 0, 0, 0, 0, 0
$ dipteres_nematoceres   <dbl> 0, 3, 4, 2, 7, 5
$ dipteres_brachyceres   <dbl> 3, 4, 10, 19, 0, 0
$ mecoptera              <dbl> 0, 0, 0, 0, 0, 0
$ siphonaptera           <dbl> 0, 0, 0, 0, 0, 0
$ trichoptera            <dbl> 0, 0, 0, 0, 0, 0
$ lepidoptera            <dbl> 0, 0, 0, 0, 2, 2
$ hymenoptera_symphytes  <dbl> 0, 0, 0, 0, 0, 0
$ hymenoptera_apocrites  <dbl> 7, 5, 9, 1, 1, 2
$ araignees              <dbl> 0, 0, 0, 0, 0, 1
$ myriapodes             <dbl> 0, 0, 0, 0, 0, 0
$ longitude              <dbl> -71.90810, -71.91132, -71.90792, -71.91162, -71…
$ latitude               <dbl> 45.38143, 45.38102, 45.38162, 45.38107, 45.3812…
$ site                   <dbl> 1, 2, 1, 2, 1, 2

Méthode alternative pour identifier automatiquement les colonnes vides :

# Identifier les colonnes avec plus de 90% de NAs
colonnes_vides <- data_insectes_clean |>
  summarise_all(~sum(is.na(.)) / length(.) * 100) |>
  gather(colonne, pourcentage_na) |>
  filter(pourcentage_na > 90)

print(colonnes_vides)
# A tibble: 0 × 2
# ℹ 2 variables: colonne <chr>, pourcentage_na <dbl>

Cette approche permet d’identifier automatiquement les colonnes problématiques dans de gros jeux de données.

7.5 Étape 22: Création d’une variable de type de récolte

Avant de transformer nos données en format long, nous devons créer une variable qui identifie le type de méthode de récolte utilisée pour chaque échantillon. Cette information est encodée dans l’identifiant de l’échantillon (echantillon_id).

7.5.1 Schéma de codage des méthodes de récolte

Les différentes méthodes d’échantillonnage sont identifiées par des codes dans les identifiants d’échantillons :

# Définition du schéma de codage
codes_recolte <- c("FF", "DB", "FO", "BBlanc", "BJaune", "M")
types_recolte <- c("filet_fauchoir", "drap_battage", "fosse", "bol_blanc", "bol_jaune", "malaise")

# Affichage du schéma de correspondance
correspondance <- data.frame(
  Code = codes_recolte,
  Type_de_recolte = types_recolte,
  Description = c(
    "Filet fauchoir - Capture d'insectes volants dans la végétation",
    "Drap de battage - Secouage de branches sur un drap",
    "Piège fosse - Capture d'insectes rampants",
    "Bol blanc - Piège coloré attractif",
    "Bol jaune - Piège coloré attractif",
    "Piège Malaise - Capture d'insectes volants"
  )
)

print(correspondance)
    Code Type_de_recolte
1     FF  filet_fauchoir
2     DB    drap_battage
3     FO           fosse
4 BBlanc       bol_blanc
5 BJaune       bol_jaune
6      M         malaise
                                                     Description
1 Filet fauchoir - Capture d'insectes volants dans la végétation
2             Drap de battage - Secouage de branches sur un drap
3                      Piège fosse - Capture d'insectes rampants
4                             Bol blanc - Piège coloré attractif
5                             Bol jaune - Piège coloré attractif
6                     Piège Malaise - Capture d'insectes volants

7.5.2 Création de la variable type_de_recolte

Nous utilisons la fonction case_when() pour attribuer le type de récolte basé sur le contenu de l’identifiant d’échantillon. Cette fonction évalue plusieurs conditions de manière séquentielle.

# Création de la variable type_de_recolte
data_insectes_final <- data_insectes_final |>
  mutate(
    type_de_recolte = case_when(
      str_detect(echantillon_id, "FF") ~ "filet_fauchoir",
      str_detect(echantillon_id, "DB") ~ "drap_battage", 
      str_detect(echantillon_id, "FO") ~ "fosse",
      str_detect(echantillon_id, "BBlanc") ~ "bol_blanc",
      str_detect(echantillon_id, "BJaune") ~ "bol_jaune",
      str_detect(echantillon_id, "M") ~ "malaise",
      TRUE ~ "non_identifie"  # Valeur par défaut si aucun pattern ne correspond
    )
  )

# Vérification de la création de la variable
table(data_insectes_final$type_de_recolte, useNA = "ifany")

     bol_jaune filet_fauchoir        malaise 
             2              2              2 

Fonctions utilisées : - case_when() : Évalue plusieurs conditions et assigne des valeurs correspondantes - str_detect() : Détecte la présence d’un pattern dans une chaîne de caractères - TRUE ~ "non_identifie" : Condition par défaut (catch-all) pour les cas non couverts

7.5.3 Vérification de la classification

Il est important de vérifier que notre classification a fonctionné correctement en examinant quelques exemples.

# Échantillonnage de quelques cas pour vérification
# Utiliser slice_sample avec un maximum sécurisé
verification <- data_insectes_final |>
  select(echantillon_id, type_de_recolte) |>
  slice_sample(n = min(20, nrow(data_insectes_final))) |>  # Prendre max 20 ou toutes les lignes si < 20
  arrange(type_de_recolte)

print("Échantillons de vérification:")
[1] "Échantillons de vérification:"
print(verification)
# A tibble: 6 × 2
  echantillon_id type_de_recolte
  <chr>          <chr>          
1 BJaune_6_2     bol_jaune      
2 BJaune_6_1     bol_jaune      
3 FF_6_1         filet_fauchoir 
4 FF_6_2         filet_fauchoir 
5 M_2_1_6        malaise        
6 M_1_1_6        malaise        
# Résumé par type de récolte
resume_types <- data_insectes_final |>
  group_by(type_de_recolte) |>
  summarise(
    nombre_echantillons = n(),
    .groups = "drop"
  ) |>
  arrange(desc(nombre_echantillons))

print("Résumé par type de récolte:")
[1] "Résumé par type de récolte:"
print(resume_types)
# A tibble: 3 × 2
  type_de_recolte nombre_echantillons
  <chr>                         <int>
1 bol_jaune                         2
2 filet_fauchoir                    2
3 malaise                           2

Avantages de cette approche : - Automatisation : Plus besoin de classifier manuellement chaque échantillon - Reproductibilité : La même règle s’applique de manière cohérente - Traçabilité : La logique de classification est explicite dans le code - Flexibilité : Facile de modifier les règles si nécessaire

Cette variable type_de_recolte nous permettra d’analyser l’efficacité relative des différentes méthodes d’échantillonnage et de comprendre quels types d’insectes sont mieux capturés par chaque méthode.

7.6 Étape 23: Transformation des données de format large vers format long

7.6.1 Problème avec les données en format large (wide format)

Les données d’insectes sont actuellement en format large : chaque groupe taxonomique (plecoptera, diptera, etc.) occupe une colonne séparée avec l’abondance comme valeur. Ce format pose plusieurs problèmes pour l’analyse et la visualisation :

Difficultés du format large : - Graphiques complexes : Difficile de créer des graphiques comparant les abondances entre groupes - Analyses statistiques : La plupart des tests statistiques requirent des données en format long - Filtrage compliqué : Impossible de filtrer facilement par groupe taxonomique - Agrégations difficiles : Calculs de totaux et moyennes par groupe compliqués

Avantages du format long : - Visualisation facile : Parfait pour ggplot2 (une variable = un axe) - Analyses groupées : Facilite les analyses par groupe taxonomique - Flexibilité : Permet filtrage, agrégation et transformation par groupe - Tidyverse-friendly : Compatible avec la philosophie des données bien organisées

# Vérification de la structure actuelle (format large)
glimpse(data_insectes_final)
Rows: 6
Columns: 33
$ echantillon_id         <chr> "FF_6_1", "FF_6_2", "BJaune_6_1", "BJaune_6_2",…
$ plecoptera             <dbl> 0, 0, 0, 0, 0, 0
$ dermaptera             <dbl> 0, 0, 0, 0, 0, 0
$ orthoptera_caeliferes  <dbl> 9, 0, 0, 0, 0, 0
$ orthoptera_ensiferes   <dbl> 1, 0, 0, 0, 0, 0
$ phasmatodea            <dbl> 0, 0, 0, 0, 0, 0
$ mantodea               <dbl> 0, 0, 0, 0, 0, 0
$ blattodea              <dbl> 0, 0, 0, 0, 0, 0
$ psocodea_phthiraptera  <dbl> 0, 0, 0, 0, 0, 0
$ psocodea_psocoptera    <dbl> 0, 0, 0, 0, 9, 10
$ thysanoptera           <dbl> 0, 1, 0, 0, 0, 0
$ hemiptera_homopteres   <dbl> 2, 19, 3, 0, 0, 3
$ hemiptera_heteropteres <dbl> 40, 14, 0, 0, 1, 8
$ raphidioptera          <dbl> 0, 0, 0, 0, 0, 0
$ megaloptera            <dbl> 0, 0, 0, 0, 0, 0
$ neuroptera             <dbl> 0, 0, 0, 0, 0, 0
$ coleopteres_apephages  <dbl> 0, 0, 0, 0, 0, 0
$ coleopteres_polyphages <dbl> 2, 0, 1, 1, 0, 0
$ strepsiptera           <dbl> 0, 0, 0, 0, 0, 0
$ dipteres_nematoceres   <dbl> 0, 3, 4, 2, 7, 5
$ dipteres_brachyceres   <dbl> 3, 4, 10, 19, 0, 0
$ mecoptera              <dbl> 0, 0, 0, 0, 0, 0
$ siphonaptera           <dbl> 0, 0, 0, 0, 0, 0
$ trichoptera            <dbl> 0, 0, 0, 0, 0, 0
$ lepidoptera            <dbl> 0, 0, 0, 0, 2, 2
$ hymenoptera_symphytes  <dbl> 0, 0, 0, 0, 0, 0
$ hymenoptera_apocrites  <dbl> 7, 5, 9, 1, 1, 2
$ araignees              <dbl> 0, 0, 0, 0, 0, 1
$ myriapodes             <dbl> 0, 0, 0, 0, 0, 0
$ longitude              <dbl> -71.90810, -71.91132, -71.90792, -71.91162, -71…
$ latitude               <dbl> 45.38143, 45.38102, 45.38162, 45.38107, 45.3812…
$ site                   <dbl> 1, 2, 1, 2, 1, 2
$ type_de_recolte        <chr> "filet_fauchoir", "filet_fauchoir", "bol_jaune"…
# Affichage des colonnes taxonomiques pour identifier la plage
names(data_insectes_final)[grep("plecoptera|myriapodes", names(data_insectes_final))]
[1] "plecoptera" "myriapodes"

7.6.2 Transformation avec pivot_longer()

Nous allons transformer les données du format large vers le format long en utilisant pivot_longer(). Cette fonction prend plusieurs colonnes et les “pivote” en deux nouvelles colonnes : une pour les noms (taxon) et une pour les valeurs (abondance).

# Transformation du format large vers format long
data_insectes_long <- data_insectes_final |>
  pivot_longer(
    cols = plecoptera:myriapodes,    # Colonnes à transformer (de plecoptera à myriapodes)
    names_to = "taxon",              # Nom de la nouvelle colonne pour les noms de colonnes
    values_to = "abondance"          # Nom de la nouvelle colonne pour les valeurs
  )

# Vérification de la transformation
glimpse(data_insectes_long)
Rows: 168
Columns: 7
$ echantillon_id  <chr> "FF_6_1", "FF_6_1", "FF_6_1", "FF_6_1", "FF_6_1", "FF_…
$ longitude       <dbl> -71.9081, -71.9081, -71.9081, -71.9081, -71.9081, -71.…
$ latitude        <dbl> 45.38143, 45.38143, 45.38143, 45.38143, 45.38143, 45.3…
$ site            <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
$ type_de_recolte <chr> "filet_fauchoir", "filet_fauchoir", "filet_fauchoir", …
$ taxon           <chr> "plecoptera", "dermaptera", "orthoptera_caeliferes", "…
$ abondance       <dbl> 0, 0, 9, 1, 0, 0, 0, 0, 0, 0, 2, 40, 0, 0, 0, 0, 2, 0,…
# Affichage des premiers échantillons pour voir la transformation
head(data_insectes_long, 20)
# A tibble: 20 × 7
   echantillon_id longitude latitude  site type_de_recolte taxon       abondance
   <chr>              <dbl>    <dbl> <dbl> <chr>           <chr>           <dbl>
 1 FF_6_1             -71.9     45.4     1 filet_fauchoir  plecoptera          0
 2 FF_6_1             -71.9     45.4     1 filet_fauchoir  dermaptera          0
 3 FF_6_1             -71.9     45.4     1 filet_fauchoir  orthoptera…         9
 4 FF_6_1             -71.9     45.4     1 filet_fauchoir  orthoptera…         1
 5 FF_6_1             -71.9     45.4     1 filet_fauchoir  phasmatodea         0
 6 FF_6_1             -71.9     45.4     1 filet_fauchoir  mantodea            0
 7 FF_6_1             -71.9     45.4     1 filet_fauchoir  blattodea           0
 8 FF_6_1             -71.9     45.4     1 filet_fauchoir  psocodea_p…         0
 9 FF_6_1             -71.9     45.4     1 filet_fauchoir  psocodea_p…         0
10 FF_6_1             -71.9     45.4     1 filet_fauchoir  thysanopte…         0
11 FF_6_1             -71.9     45.4     1 filet_fauchoir  hemiptera_…         2
12 FF_6_1             -71.9     45.4     1 filet_fauchoir  hemiptera_…        40
13 FF_6_1             -71.9     45.4     1 filet_fauchoir  raphidiopt…         0
14 FF_6_1             -71.9     45.4     1 filet_fauchoir  megaloptera         0
15 FF_6_1             -71.9     45.4     1 filet_fauchoir  neuroptera          0
16 FF_6_1             -71.9     45.4     1 filet_fauchoir  coleoptere…         0
17 FF_6_1             -71.9     45.4     1 filet_fauchoir  coleoptere…         2
18 FF_6_1             -71.9     45.4     1 filet_fauchoir  strepsipte…         0
19 FF_6_1             -71.9     45.4     1 filet_fauchoir  dipteres_n…         0
20 FF_6_1             -71.9     45.4     1 filet_fauchoir  dipteres_b…         3

Explication de la transformation : - cols = plecoptera:myriapodes : Sélectionne toutes les colonnes de plecoptera à myriapodes - names_to = "taxon" : Crée une nouvelle colonne “taxon” contenant les noms des anciennes colonnes - values_to = "abondance" : Crée une nouvelle colonne “abondance” contenant les valeurs

Résultat : Chaque ligne représente maintenant un échantillon × taxon, avec l’abondance correspondante.

# Vérification des groupes taxonomiques uniques
unique(data_insectes_long$taxon)
 [1] "plecoptera"             "dermaptera"             "orthoptera_caeliferes" 
 [4] "orthoptera_ensiferes"   "phasmatodea"            "mantodea"              
 [7] "blattodea"              "psocodea_phthiraptera"  "psocodea_psocoptera"   
[10] "thysanoptera"           "hemiptera_homopteres"   "hemiptera_heteropteres"
[13] "raphidioptera"          "megaloptera"            "neuroptera"            
[16] "coleopteres_apephages"  "coleopteres_polyphages" "strepsiptera"          
[19] "dipteres_nematoceres"   "dipteres_brachyceres"   "mecoptera"             
[22] "siphonaptera"           "trichoptera"            "lepidoptera"           
[25] "hymenoptera_symphytes"  "hymenoptera_apocrites"  "araignees"             
[28] "myriapodes"            
# Résumé des abondances par taxon
data_insectes_long |>
  group_by(taxon) |>
  summarise(
    nombre_observations = n(),
    abondance_totale = sum(abondance, na.rm = TRUE),
    abondance_moyenne = mean(abondance, na.rm = TRUE),
    abondance_max = max(abondance, na.rm = TRUE)
  ) |>
  arrange(desc(abondance_totale))
# A tibble: 28 × 5
   taxon    nombre_observations abondance_totale abondance_moyenne abondance_max
   <chr>                  <int>            <dbl>             <dbl>         <dbl>
 1 hemipte…                   6               63            10.5              40
 2 diptere…                   6               36             6                19
 3 hemipte…                   6               27             4.5              19
 4 hymenop…                   6               25             4.17              9
 5 diptere…                   6               21             3.5               7
 6 psocode…                   6               19             3.17             10
 7 orthopt…                   6                9             1.5               9
 8 coleopt…                   6                4             0.667             2
 9 lepidop…                   6                4             0.667             2
10 araigne…                   6                1             0.167             1
# ℹ 18 more rows

Nous pouvons maintenant passer à la partie excitante de l’analyse: la représentation graphique des données de captures.

8 Visualisation avancée et bonnes pratiques

8.1 Étape 24: Bonnes pratiques de visualisation - Éviter les graphiques en secteurs

Avant de créer nos visualisations, il est important de discuter des bonnes pratiques en matière de graphiques. Un des graphiques les plus problématiques, mais malheureusement très populaire, est le graphique en secteurs (pie chart).

8.1.1 Problèmes des graphiques en secteurs

Les graphiques en secteurs posent plusieurs problèmes majeurs qui nuisent à la compréhension des données :

8.1.1.1 1. Difficulté de comparaison des angles

# Exemple problématique avec un graphique en secteurs
# (Code commenté pour montrer ce qu'il NE faut PAS faire)

# Données d'exemple pour la démonstration
exemple_donnees <- data.frame(
  taxon = c("Diptera", "Coleoptera", "Hymenoptera", "Lepidoptera", "Hemiptera"),
  abondance = c(145, 89, 123, 67, 98)
)

# MAUVAISE pratique - Graphique en secteurs (ne pas utiliser!)
ggplot(exemple_donnees, aes(x = "", y = abondance, fill = taxon)) +
   geom_bar(stat = "identity", width = 1) +
   coord_polar("y", start = 0) +
   labs(title = "MAUVAIS: Difficile de comparer les proportions") +
   theme_void()
Figure 9: Exemple de graphique en secteurs problématique - difficile de comparer les proportions avec précision.

8.1.1.2 2. Limitations cognitives

  • Perception des angles : L’œil humain est mauvais pour comparer des angles
  • Comparaisons multiples : Impossible de comparer plus de 2-3 segments facilement
  • Valeurs exactes : Difficile d’estimer les pourcentages précis
  • Ordre : Pas d’ordre logique évident pour les segments

8.1.2 Alternative 1: Graphiques en barres empilées

Les graphiques en barres empilées permettent de mieux comparer les proportions tout en montrant la contribution de chaque groupe.

# BONNE pratique - Graphique en barres empilées
stacked_bar <- exemple_donnees |>
  mutate(
    pourcentage = abondance / sum(abondance) * 100,
    taxon = reorder(taxon, abondance)  # Ordonner par abondance
  ) |>
  ggplot(aes(x = "Échantillon", y = pourcentage, fill = taxon)) +
  geom_bar(stat = "identity", width = 0.6) +
  geom_text(aes(label = paste0(round(pourcentage, 1), "%")), 
            position = position_stack(vjust = 0.5),
            color = "white", fontface = "bold", size = 3.5) +
  labs(
    title = "MIEUX: Graphique en barres empilées",
    subtitle = "Proportions plus faciles à comparer",
    y = "Pourcentage (%)",
    x = NULL,
    fill = "Groupe taxonomique"
  ) +
  scale_fill_viridis_d(option = "plasma") +
  theme_minimal() +
  theme(
    axis.text.x = element_blank(),
    axis.ticks.x = element_blank(),
    legend.position = "right"
  )

print(stacked_bar)
Figure 10: Graphique en barres empilées - amélioration par rapport aux secteurs pour comparer les proportions taxonomiques.

Avantages des barres empilées : - Longueurs comparables : Plus facile de comparer les longueurs que les angles - Valeurs précises : Possibilité d’ajouter les pourcentages exacts - Ordre logique : Peut être ordonné par importance - Échelle commune : Tous les segments partagent la même échelle

8.1.3 Alternative 2: Graphiques en sucettes (Lollipop plots)

Les graphiques en sucettes sont excellents pour montrer des proportions ou des valeurs absolues de manière claire et attrayante.

# EXCELLENTE pratique - Graphique en sucettes
lollipop_plot <- exemple_donnees |>
  mutate(
    pourcentage = abondance / sum(abondance) * 100,
    taxon = reorder(taxon, pourcentage)  # Ordonner par pourcentage
  ) |>
  ggplot(aes(x = taxon, y = pourcentage)) +
  geom_segment(aes(xend = taxon, yend = 0), 
               color = "steelblue3", linewidth = 1.2) +
  geom_point(color = "steelblue3", size = 4) +
  geom_text(aes(label = paste0(round(pourcentage, 1), "%")), 
            vjust = -1, fontface = "bold", size = 3.5) +
  labs(
    title = "OPTIMAL: Graphique en sucettes",
    subtitle = "Comparaisons précises et esthétique moderne",
    y = "Pourcentage (%)",
    x = "Groupe taxonomique"
  ) +
  theme_minimal() +
  theme(
    panel.grid.major.x = element_blank(),
    panel.grid.minor = element_blank(),
    axis.text.x = element_text(angle = 45, hjust = 1, size = 10),
    plot.title = element_text(size = 14, face = "bold"),
    plot.subtitle = element_text(size = 12, color = "gray50")
  ) +
  coord_flip()  # Rotation pour meilleure lisibilité

print(lollipop_plot)
Figure 11: Graphique en sucettes - solution optimale pour comparer les proportions avec précision et esthétique moderne.

Avantages des graphiques en sucettes : - Comparaisons précises : Position sur l’axe facilement comparable - Esthétique moderne : Apparence propre et professionnelle - Espace optimisé : Moins d’encombrement visuel - Valeurs exactes : Lecture précise des valeurs - Extensibilité : Fonctionne bien avec de nombreuses catégories

8.1.4 Recommandations générales

Quand utiliser chaque type :

  1. Barres empilées :
    • Quand vous voulez montrer les parties d’un tout
    • Pour comparer des compositions entre groupes
    • Maximum 5-7 catégories pour la lisibilité
  2. Graphiques en sucettes :
    • Pour comparer des valeurs individuelles
    • Quand l’ordre/ranking est important
    • Excellent pour de nombreuses catégories
  3. JAMAIS de graphiques en secteurs :
    • Sauf si vous avez exactement 2 catégories
    • Et que la différence est très marquée (ex: 80% vs 20%)

Règle d’or : Si vous pouvez remplacer un graphique en secteurs par un graphique en barres, faites-le toujours !

8.2 Étape 25: Application pratique - Visualisation des captures par site et type de piège

Maintenant, appliquons ces bonnes pratiques de visualisation à nos données entomologiques réelles. Nous allons comparer l’abondance des groupes taxonomiques par site et type de méthode de récolte.

8.2.1 Préparation des données pour la visualisation

Avant de créer nos graphiques, nous devons préparer et nettoyer les données en éliminant les taxons avec une abondance nulle et en calculant les proportions.

# Préparation des données : suppression des taxons avec abondance nulle et calcul des proportions
donnees_viz <- data_insectes_long |>
  filter(abondance > 0) |>  # Éliminer les taxons sans captures
  group_by(site, type_de_recolte, taxon) |>
  summarise(abondance_totale = sum(abondance, na.rm = TRUE), .groups = "drop") |>
  group_by(site, type_de_recolte) |>
  mutate(
    pourcentage = abondance_totale / sum(abondance_totale) * 100,
    total_site_methode = sum(abondance_totale)
  ) |>
  ungroup() |>
  filter(total_site_methode >= 5) |>  # Garder seulement les combinaisons avec ≥5 individus
  arrange(site, type_de_recolte, desc(abondance_totale))

# Affichage d'un aperçu des données préparées
glimpse(donnees_viz)
Rows: 34
Columns: 6
$ site               <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
$ type_de_recolte    <chr> "bol_jaune", "bol_jaune", "bol_jaune", "bol_jaune",…
$ taxon              <chr> "dipteres_brachyceres", "hymenoptera_apocrites", "d…
$ abondance_totale   <dbl> 10, 9, 4, 3, 1, 40, 9, 7, 3, 2, 2, 1, 9, 7, 2, 1, 1…
$ pourcentage        <dbl> 37.037037, 33.333333, 14.814815, 11.111111, 3.70370…
$ total_site_methode <dbl> 27, 27, 27, 27, 27, 64, 64, 64, 64, 64, 64, 64, 20,…
print("Aperçu des données pour visualisation:")
[1] "Aperçu des données pour visualisation:"
head(donnees_viz, 10)
# A tibble: 10 × 6
    site type_de_recolte taxon   abondance_totale pourcentage total_site_methode
   <dbl> <chr>           <chr>              <dbl>       <dbl>              <dbl>
 1     1 bol_jaune       dipter…               10       37.0                  27
 2     1 bol_jaune       hymeno…                9       33.3                  27
 3     1 bol_jaune       dipter…                4       14.8                  27
 4     1 bol_jaune       hemipt…                3       11.1                  27
 5     1 bol_jaune       coleop…                1        3.70                 27
 6     1 filet_fauchoir  hemipt…               40       62.5                  64
 7     1 filet_fauchoir  orthop…                9       14.1                  64
 8     1 filet_fauchoir  hymeno…                7       10.9                  64
 9     1 filet_fauchoir  dipter…                3        4.69                 64
10     1 filet_fauchoir  coleop…                2        3.12                 64

8.2.2 Choix de la méthode de visualisation appropriée

Avant de créer nos visualisations, il est important de choisir la méthode la plus appropriée en fonction du nombre de catégories (taxa) à représenter.

# Vérifier le nombre de taxons uniques dans nos données
nombre_taxons <- donnees_viz |> 
  distinct(taxon) |> 
  nrow()

print(paste("Nombre total de taxons à visualiser:", nombre_taxons))
[1] "Nombre total de taxons à visualiser: 12"
# Vérifier la distribution des taxons par site
distribution_taxons <- donnees_viz |>
  group_by(site) |>
  summarise(
    nombre_taxons = n_distinct(taxon),
    .groups = "drop"
  )

print("Distribution des taxons par site:")
[1] "Distribution des taxons par site:"
print(distribution_taxons)
# A tibble: 2 × 2
   site nombre_taxons
  <dbl>         <int>
1     1            10
2     2            10

Problème avec les graphiques en barres empilées pour de nombreux taxons :

Quand le nombre de catégories dépasse 8-10 éléments, les graphiques en barres empilées deviennent : - Difficiles à lire : Trop de couleurs différentes - Peu informatifs : Les petites catégories sont invisibles - Problématiques pour l’accessibilité : Difficile de distinguer les couleurs similaires - Surchargés : La légende devient encombrante

Solution recommandée : Utiliser des graphiques en sucettes (lollipop plots) qui : - Permettent de comparer facilement les valeurs individuelles - Fonctionnent bien avec de nombreuses catégories - Sont plus lisibles même avec beaucoup de données - Peuvent être facettés par méthode de récolte

8.2.3 Graphiques en sucettes par site et méthode

Les graphiques en sucettes offrent une vision plus claire des abondances relatives et facilitent les comparaisons entre taxons, même avec de nombreux taxons.

# Fonction pour créer un graphique en sucettes pour une combinaison spécifique
create_lollipop_specific <- function(data, site_num, type_recolte, n_taxons = 8) {
  # Nettoyer le nom du type de récolte pour l'affichage
  type_clean <- str_replace_all(type_recolte, "_", " ") |> str_to_title()
  
  data |>
    filter(site == site_num, type_de_recolte == type_recolte) |>
    # Garder les n taxons les plus abondants
    slice_max(order_by = pourcentage, n = n_taxons) |>
    mutate(taxon = reorder(taxon, pourcentage)) |>
    ggplot(aes(x = taxon, y = pourcentage)) +
    geom_segment(aes(xend = taxon, yend = 0), 
                 color = "steelblue3", linewidth = 1.2) +
    geom_point(color = "steelblue3", size = 3.5) +
    geom_text(aes(label = paste0(round(pourcentage, 1), "%")), 
              hjust = -0.2, fontface = "bold", size = 3) +
    labs(
      title = paste("Site", site_num, "-", type_clean),
      y = "Pourcentage (%)",
      x = NULL
    ) +
    theme_minimal() +
    theme(
      axis.text.x = element_text(size = 8),
      axis.text.y = element_text(size = 8),
      panel.grid.major.y = element_blank(),
      panel.grid.minor = element_blank(),
      plot.title = element_text(size = 10, face = "bold", hjust = 0.5),
      axis.title.x = element_text(size = 9)
    ) +
    coord_flip() +
    scale_y_continuous(expand = expansion(mult = c(0.02, 0.15)))
}

# Obtenir toutes les combinaisons site x type_de_recolte
combinaisons <- donnees_viz |>
  distinct(site, type_de_recolte) |>
  arrange(type_de_recolte, site)

print("Combinaisons site x type de récolte disponibles:")
[1] "Combinaisons site x type de récolte disponibles:"
print(combinaisons)
# A tibble: 6 × 2
   site type_de_recolte
  <dbl> <chr>          
1     1 bol_jaune      
2     2 bol_jaune      
3     1 filet_fauchoir 
4     2 filet_fauchoir 
5     1 malaise        
6     2 malaise        
# Créer tous les graphiques individuels
plots_list <- list()
for(i in 1:nrow(combinaisons)) {
  site_i <- combinaisons$site[i]
  type_i <- combinaisons$type_de_recolte[i]
  plot_name <- paste0("plot_s", site_i, "_", type_i)
  
  plots_list[[plot_name]] <- create_lollipop_specific(donnees_viz, site_i, type_i)
}

# Organiser les graphiques par type de récolte (rows) et site (columns)
types_recolte <- unique(combinaisons$type_de_recolte)
sites <- unique(combinaisons$site)

print(paste("Types de récolte:", paste(types_recolte, collapse = ", ")))
[1] "Types de récolte: bol_jaune, filet_fauchoir, malaise"
print(paste("Sites:", paste(sites, collapse = ", ")))
[1] "Sites: 1, 2"
# Créer la matrice de graphiques avec patchwork
lollipop_combined <- wrap_plots(plots_list, ncol = length(sites), byrow = TRUE) +
  plot_annotation(
    title = "Composition taxonomique par site et méthode de récolte",
    subtitle = "Pourcentages des groupes taxonomiques dominants (top 8 par combinaison)",
    caption = "Colonnes = Sites | Lignes = Méthodes de récolte"
  )

print(lollipop_combined)
Figure 12: Composition taxonomique par site et méthode de récolte. Les graphiques en sucettes permettent de comparer facilement les abondances relatives des groupes taxonomiques dominants.

8.2.4 Analyse des résultats des graphiques en sucettes

Les graphiques en sucettes nous permettent d’identifier clairement les taxons les plus abondants par site et méthode de récolte.

# Charger tinytable pour créer des tableaux de qualité professionnelle
library(tinytable)

# Tableau résumé pour accompagner les visualisations
resume_captures <- donnees_viz |>
  group_by(site, type_de_recolte) |>
  summarise(
    nb_taxons = n(),
    abondance_totale = sum(abondance_totale),
    taxon_dominant = taxon[which.max(abondance_totale)],
    pourcentage_dominant = max(pourcentage),
    .groups = "drop"
  ) |>
  arrange(site, desc(abondance_totale)) |>
  # Améliorer les noms de colonnes pour l'affichage
  mutate(
    type_de_recolte = str_replace_all(type_de_recolte, "_", " ") |> str_to_title(),
    pourcentage_dominant = round(pourcentage_dominant, 1)
  ) |>
  rename(
    Site = site,
    `Méthode de récolte` = type_de_recolte,
    `Nombre de taxons` = nb_taxons,
    `Abondance totale` = abondance_totale,
    `Taxon dominant` = taxon_dominant,
    `Pourcentage dominant (%)` = pourcentage_dominant
  )

# Créer le tableau avec tinytable
tableau_resume <- resume_captures |>
  tt() |>
  style_tt(
    bootstrap_class = "table table-striped table-hover",
    align = "llcccr"
  ) |>
  format_tt(
    j = 4, # "Abondance totale" (index utilisé car le nom contient des espaces)
    fn = function(x) format(x, big.mark = " ", scientific = FALSE)
  ) |>
  format_tt(
    j = 6, # "Pourcentage dominant (%)" (index utilisé car le nom contient des parenthèses)
    fn = function(x) paste0(x, "%")
  ) |>
  style_tt(
    i = 0,  # En-têtes
    bold = TRUE,
    background = "lightgray",
    align = "c"
  )

# Afficher le tableau avec une note explicative
tableau_resume
cat("Note: Tableau résumé des captures entomologiques par site et méthode de récolte.")
Note: Tableau résumé des captures entomologiques par site et méthode de récolte.
cat("\nLe taxon dominant correspond au groupe le plus abondant pour chaque combinaison.")

Le taxon dominant correspond au groupe le plus abondant pour chaque combinaison.
Table 2: Résumé des captures entomologiques par site et méthode de récolte, montrant la diversité taxonomique et les groupes dominants.
Site Méthode de récolte Nombre de taxons Abondance totale Taxon dominant Pourcentage dominant (%)
1 Filet Fauchoir 7 64 hemiptera_heteropteres 62.5%
1 Bol Jaune 5 27 dipteres_brachyceres 37%
1 Malaise 5 20 psocodea_psocoptera 45%
2 Filet Fauchoir 6 46 hemiptera_homopteres 41.3%
2 Malaise 7 31 psocodea_psocoptera 32.3%
2 Bol Jaune 4 23 dipteres_brachyceres 82.6%

8.2.5 Exportation du tableau pour Word

Tinytable offre plusieurs options pour exporter les tableaux dans des formats compatibles avec Microsoft Word.

# Option 1: Sauvegarder en format Word (.docx)
# Le tableau sera intégré dans un document Word
save_tt(tableau_resume, 
        output = "tableau_resume_captures.docx",
        overwrite = TRUE)

# Option 2: Sauvegarder en HTML (peut être copié-collé dans Word)
save_tt(tableau_resume, 
        output = "tableau_resume_captures.html",
        overwrite = TRUE)

print("Tableaux sauvegardés dans les formats suivants:")
print("- tableau_resume_captures.docx (Word)")
print("- tableau_resume_captures.html (HTML)")

Avantages de tinytable pour les publications scientifiques :

  1. Formatage professionnel : Tableaux avec bordures, alignement et styles
  2. Compatibilité : Export direct vers Word, HTML, LaTeX, PDF
  3. Personnalisation : Contrôle total sur l’apparence et le formatage
  4. Notes et légendes : Ajout facile de notes explicatives
  5. Formatage conditionnel : Mise en forme basée sur les valeurs

Workflow recommandé pour Word : 1. Créer le tableau avec tinytable dans R/Quarto 2. Exporter en format .docx 3. Ouvrir dans Word pour intégration finale 4. Ajuster la mise en page si nécessaire

Insights tirés de ces visualisations :

  1. Efficacité des méthodes : Les graphiques permettent de comparer l’efficacité relative de chaque méthode de capture
  2. Spécificité des habitats : Différences de composition entre sites forestiers et ouverts
  3. Sélectivité des pièges : Certains taxons sont mieux capturés par certaines méthodes
  4. Diversité comparative : Comparaison du nombre de taxons capturés par méthode

Ces visualisations démontrent la supériorité des graphiques en barres et en sucettes par rapport aux graphiques en secteurs pour analyser des données écologiques complexes.

8.2.6 Interprétation des résultats

Points clés à retenir :

  1. Efficacité des méthodes : Les graphiques permettent de comparer l’efficacité relative des différents types de pièges
  2. Spécificité des sites : Chaque site peut avoir des profils taxonomiques différents
  3. Dominance taxonomique : Identification des taxons les plus abondants par site et méthode
  4. Diversité : Évaluation de la richesse taxonomique par méthode de collecte

Applications pratiques : - Optimisation des protocoles d’échantillonnage - Planification des campagnes de terrain - Études de biodiversité comparative - Monitoring environnemental

9 Conclusion et perspectives

9.1 Conclusion

Ce tutoriel vous a guidé à travers une analyse complète de données entomologiques spatio-temporelles en R, couvrant l’ensemble du workflow depuis l’organisation des projets jusqu’à la publication des résultats. Vous avez acquis des compétences essentielles dans :

9.1.1 Compétences techniques acquises

9.1.1.1 1. Organisation et reproductibilité des projets

  • Gestion des projets R pour une recherche reproductible
  • Évitement des pièges comme setwd() qui brisent la reproductibilité
  • Utilisation du package here pour des chemins relatifs portables
  • Structure organisée des dossiers pour faciliter la collaboration

9.1.1.2 2. Maîtrise de l’écosystème tidyverse

  • Philosophie des données bien organisées (tidy data)
  • Utilisation experte de l’opérateur pipe (|>) pour un code lisible
  • Manipulation avancée avec dplyr (filter, select, mutate, summarise)
  • Restructuration des données avec tidyr (pivot_longer, pivot_wider)

9.1.1.3 3. Visualisation professionnelle avec ggplot2

  • Grammaire des graphiques pour construire des visualisations par couches
  • Maîtrise des thèmes pré-formatés et personnalisés
  • Création de graphiques publication-ready avec annotations détaillées
  • Sauvegarde optimisée avec ggsave() selon les standards de publication

9.1.1.4 4. Analyses spatiales et cartographiques

  • Manipulation de données spatiales avec le package sf
  • Création de cartes contextuelles avec ggplot2 et ggspatial
  • Extraction et transformation de coordonnées pour différents types de géométries
  • Jointures spatiales entre jeux de données géographiques

9.1.1.5 5. Intégration de données climatiques

  • Accès aux données NASA POWER via l’API automatisée
  • Gestion des fuseaux horaires et conversions temporelles
  • Analyse de séries temporelles météorologiques
  • Visualisation annotée des conditions climatiques

9.1.1.6 6. Manipulation avancée des données

  • Nettoyage automatisé des noms de colonnes avec janitor
  • Détection et suppression des colonnes inutiles
  • Création de variables dérivées avec case_when() et str_detect()
  • Transformation des formats de données pour l’analyse

9.1.1.7 7. Bonnes pratiques de visualisation

  • Évitement des mauvaises pratiques (graphiques en secteurs)
  • Choix approprié du type de graphique selon le nombre de catégories
  • Création de visualisations comparatives avec patchwork
  • Utilisation des couleurs et légendes pour une communication claire

9.1.1.8 8. Documentation et publication

  • Création de tableaux professionnels avec tinytable
  • Export vers formats compatibles Word pour collaboration
  • Documentation reproductible avec Quarto/R Markdown
  • Workflow complet de l’analyse à la publication

9.1.2 Bonnes pratiques méthodologiques retenues

9.1.2.1 Reproductibilité et collaboration

  • Projets R organisés : Structure claire et chemins relatifs
  • Code documenté : Commentaires détaillés pour la compréhension
  • Contrôle de version : Prêt pour l’intégration Git/GitHub
  • Partage facilité : Projets portables entre collaborateurs

9.1.2.2 Qualité des données et analyses

  • Exploration systématique : Visualisation avant analyse statistique
  • Validation continue : Vérification des données à chaque étape
  • Nettoyage méthodique : Standardisation et optimisation
  • Traçabilité complète : Chaque transformation documentée

9.1.2.3 Communication scientifique

  • Visualisations professionnelles : Standards de publication respectés
  • Légendes informatives : Context et métadonnées incluses
  • Formats adaptés : Selon le public et le medium de diffusion
  • Accessibility : Choix de couleurs et polices appropriés

9.1.3 Applications dans la recherche entomologique

Les compétences développées dans ce tutoriel s’appliquent directement à :

9.1.3.1 Écologie et biodiversité

  • Monitoring des populations d’insectes dans le temps et l’espace
  • Analyses de diversité taxonomique et fonctionnelle
  • Études de distribution et modélisation de niche écologique
  • Évaluation de l’impact des changements environnementaux

9.1.3.2 Recherche appliquée

  • Gestion des ravageurs agricoles et forestiers
  • Conservation des espèces menacées ou bénéfiques
  • Surveillance entomologique pour la santé publique
  • Études d’efficacité des méthodes de contrôle

9.1.3.3 Recherche fondamentale

  • Écologie des communautés et réseaux trophiques
  • Biogéographie et phylogéographie
  • Écologie comportementale et sélection d’habitat
  • Réponses aux stress climatiques et anthropiques

9.1.4 Workflow reproductible recommandé

Pour vos futurs projets, suivez cette séquence éprouvée :

  1. Initialisation : Créer un projet R avec structure organisée
  2. Importation : Charger les données avec chemins relatifs
  3. Exploration : Visualiser et comprendre les données brutes
  4. Nettoyage : Standardiser et valider les données
  5. Transformation : Créer les variables d’analyse nécessaires
  6. Analyse : Conduire les analyses statistiques et spatiales
  7. Visualisation : Créer les graphiques de communication
  8. Documentation : Rédiger le rapport avec Quarto
  9. Validation : Tester la reproductibilité sur un autre système
  10. Partage : Publier le code et les données selon les standards ouverts

9.1.5 Ressources pour approfondir vos compétences

9.1.5.1 Documentation officielle et guides

  • R for Data Science : https://r4ds.hadley.nz/ (bible du tidyverse)
  • Spatial Data Science : https://r-spatial.org/ (analyses spatiales en R)
  • ggplot2 Book : https://ggplot2-book.org/ (maîtrise complète de ggplot2)
  • Quarto Documentation : https://quarto.org/ (publication scientifique)

9.1.5.2 Packages et outils spécialisés

  • Package sf : https://r-spatial.github.io/sf/ (données spatiales)
  • NASA POWER : https://power.larc.nasa.gov/ (données climatiques)
  • Package janitor : https://sfirke.github.io/janitor/ (nettoyage de données)
  • Package patchwork : https://patchwork.data-imaginist.com/ (composition de graphiques)
  • Package tinytable : https://vincentarelbundock.github.io/tinytable/ (tableaux professionnels)

9.1.5.3 Visualisation et design

  • R Graph Gallery : https://r-graph-gallery.com/ (inspiration et code)
  • Data Visualization Handbook : https://datavizproject.com/ (choix du bon graphique)
  • ColorBrewer : https://colorbrewer2.org/ (palettes de couleurs scientifiques)
  • Fundamentals of Data Visualization : https://clauswilke.com/dataviz/ (théorie)

9.1.5.4 Reproductibilité et bonnes pratiques

  • renv Package : https://rstudio.github.io/renv/ (gestion des dépendances)
  • here Package : https://here.r-lib.org/ (chemins relatifs)
  • Happy Git with R : https://happygitwithr.com/ (contrôle de version)
  • Reproducible Research with R : https://www.crcpress.com/reproducible-research-with-r-and-r-studio/

9.1.5.5 Communautés et support

  • RStudio Community : https://community.rstudio.com/ (forum d’entraide)
  • Stack Overflow : https://stackoverflow.com/questions/tagged/r (questions techniques)
  • R-bloggers : https://www.r-bloggers.com/ (actualités et tutoriels)
  • #RStats Twitter : Communauté active sur les réseaux sociaux

9.1.5.6 Formation continue

  • Posit Academy : https://academy.posit.co/ (cours officiels RStudio)
  • DataCamp : https://www.datacamp.com/courses/r (cours interactifs)
  • Coursera R Specialization : https://www.coursera.org/specializations/r (université Johns Hopkins)
  • edX MITx : https://www.edx.org/ (cours universitaires en ligne)

9.1.6 Perspectives d’avancement

9.1.6.1 Compétences à développer ensuite

  • Analyses statistiques avancées : modèles mixtes, GLM, machine learning
  • Analyses phylogénétiques : packages ape, phytools, ggtree
  • Modélisation spatiale : krigeage, modèles de distribution d’espèces
  • Applications Shiny : interfaces interactives pour vos analyses
  • Packages R personnalisés : développement d’outils spécialisés

9.1.6.2 Intégration avec d’autres outils

  • QGIS : SIG complémentaire pour analyses spatiales complexes
  • MaxEnt/ENMeval : modélisation de niche écologique
  • GBIF : accès aux données de biodiversité mondiales
  • iNaturalist : science participative et validation taxonomique
  • Docker/Singularity : conteneurisation pour reproductibilité maximale

9.1.7 Message final

La maîtrise de R et de ses écosystèmes représente un investissement majeur pour votre carrière scientifique. Les compétences acquises dans ce tutoriel constituent une base solide pour :

  • Conduire des recherches reproductibles de haute qualité
  • Collaborer efficacement avec la communauté scientifique internationale
  • Publier dans les meilleures revues avec des analyses robustes
  • Contribuer à la science ouverte et aux bonnes pratiques de recherche

Continuez à pratiquer, expérimenter et partager vos découvertes. La communauté R est accueillante et toujours prête à aider les nouveaux utilisateurs à progresser.

Bonne continuation dans vos analyses entomologiques ! 🐛📊🌍


9.2 Gabarit de rapport étudiant

Un gabarit Quarto de rapport de laboratoire est fourni pour vous aider à structurer votre propre analyse spatio-temporelle de données entomologiques.