Comment compléter les lignes manquantes d'un jeu de données et les rendre explicites ?
🪰 Récemment, je me suis retrouvée avec un jeu de données correspondant à des piégeages d’insectes où les observations sans insectes piégés n’ont pas été notées.
Ça arrive et c’est normal.
⚙️ Sauf que quand il s’agit de faire des graphiques, puis des modèles stats, selon la question, il est parfois nécessaire de prendre en compte ces zéros !
💡 Ici, j’explique comment utiliser la fonction complete()
du package tidyr pour ajouter les lignes manquantes et les remplir avec des zéros (où ce que tu veux !).
📦 Je montre un cas particulier où la structure des variables est emboîtée, ce qui fait que l’utilisation de complete()
n’est pas tout à fait triviale.
Chargement des packages
library(tibble) # création de tables
library(tidyr) # nettoyage de tables
library(ggplot2) # graphiques
library(dplyr) # manipulation de tables
Remarque : les packages du tidyverse les plus couramment utilisés dont ceux présents ci-dessus peuvent être chargé en une seule ligne de commande avec
library(tidyverse)
.
Création d’un jeu de données exemple
captures <- tribble(
~Site, ~Date, ~Piege, ~Nb_captures,
"Site A", "Date 1", "a", 3L,
"Site A", "Date 1", "b", 2L,
"Site A", "Date 2", "a", 8L,
"Site A", "Date 2", "b", 5L,
"Site A", "Date 3", "a", 1L,
"Site A", "Date 4", "a", 3L,
"Site A", "Date 4", "b", 6L,
"Site B", "Date 5", "c", 3L,
"Site B", "Date 5", "d", 3L,
"Site B", "Date 5", "e", 2L,
"Site B", "Date 6", "c", 2L,
"Site B", "Date 6", "e", 7L,
"Site B", "Date 7", "c", 5L,
"Site B", "Date 7", "d", 4L,
"Site B", "Date 7", "e", 1L
)
Il s’agit de données totalement fictives concernant 2 Site
s échantillonnés respectivement à 2 et 3 endroits (Piege
).
L’objectif est de compter des individus à intervalles de temps régulier aux différents points de capture.
Deux points à noter :
- Les
Date
s d’observation n’ont pas été les mêmes pour chaque site. - Quand aucun individu n’a été observé, il n’y a pas de ligne dans le jeu de données (dans l’exemple, dans le
site A
, ladate 3
pour le piègeb
n’est pas présente)
Une table de contingence (qui compte le nombre d’occurence d’une combinaison d’événements) permet de mettre ça en évidence :
ftable(Site + Piege ~ Date, data = captures)
## Site Site A Site B
## Piege a b c d e a b c d e
## Date
## Date 1 1 1 0 0 0 0 0 0 0 0
## Date 2 1 1 0 0 0 0 0 0 0 0
## Date 3 1 0 0 0 0 0 0 0 0 0
## Date 4 1 1 0 0 0 0 0 0 0 0
## Date 5 0 0 0 0 0 0 0 1 1 1
## Date 6 0 0 0 0 0 0 0 1 0 1
## Date 7 0 0 0 0 0 0 0 1 1 1
ou alors
ftable(Site ~ Piege, data = captures)
## Site Site A Site B
## Piege
## a 4 0
## b 3 0
## c 0 3
## d 0 2
## e 0 3
Si on fait un graphique à ce stade, ça donne, par exemple :
ggplot(captures) +
aes(x = Date, y = Nb_captures, colour = Piege, group = Piege) +
geom_line() +
geom_point() +
facet_wrap(~ Site, scales = "free_x")
C’est subtil, mais regarde bien : les lignes b
et d
ne passent pas par toutes les dates !
Ajout des observations manquantes pour les rendre explicite
La fonction complete()
du package tidyr permet d’écrire de nouvelles lignes dans le jeu de données de telle sorte à préciser qu’il y avait 0 captures dans le piège ces jour-là !
Sauf que comme les dates et les noms des pièges ne sont pas les mêmes dans les 2 sites, ce n’est pas si simple, il faut le préciser à R.
Si on ne précise pas, toutes les combinaisons de site, piège et date sont créées :
captures %>%
complete(Site, Piege, Date, fill = list(Nb_captures = 0)) # fill permet de préciser la valeur de remplacement pour chaque colonne d'intérêt
## # A tibble: 70 × 4
## Site Piege Date Nb_captures
## <chr> <chr> <chr> <int>
## 1 Site A a Date 1 3
## 2 Site A a Date 2 8
## 3 Site A a Date 3 1
## 4 Site A a Date 4 3
## 5 Site A a Date 5 0
## 6 Site A a Date 6 0
## 7 Site A a Date 7 0
## 8 Site A b Date 1 2
## 9 Site A b Date 2 5
## 10 Site A b Date 3 0
## # ℹ 60 more rows
Or, on s’attend à récupérer :
- 4 dates \(\times\) 2 points de capture = 8 lignes pour le site A
- 3 dates \(\times\) 3 points de capture = 9 lignes pour le site B
Il faut préciser que les variables Piege
et Date
sont emboîtées dans la variable Site
:
captures_complet <- captures %>%
group_by(Site) %>% # un calcul par site
complete(Date, Piege, fill = list(Nb_captures = 0)) %>% # toutes les combinaisons de date et piège par site
ungroup() # pour dégrouper le jeu de données
captures_complet
## # A tibble: 17 × 4
## Site Date Piege Nb_captures
## <chr> <chr> <chr> <int>
## 1 Site A Date 1 a 3
## 2 Site A Date 1 b 2
## 3 Site A Date 2 a 8
## 4 Site A Date 2 b 5
## 5 Site A Date 3 a 1
## 6 Site A Date 3 b 0
## 7 Site A Date 4 a 3
## 8 Site A Date 4 b 6
## 9 Site B Date 5 c 3
## 10 Site B Date 5 d 3
## 11 Site B Date 5 e 2
## 12 Site B Date 6 c 2
## 13 Site B Date 6 d 0
## 14 Site B Date 6 e 7
## 15 Site B Date 7 c 5
## 16 Site B Date 7 d 4
## 17 Site B Date 7 e 1
Hop, et voilà : on obtient bien 8 + 9
lignes, cette fois.
Un petit graphique pour la fin :
ggplot(captures_complet) +
aes(x = Date, y = Nb_captures, colour = Piege, group = Piege) +
geom_line() +
geom_point() +
facet_wrap(~ Site, scales = "free_x")