8  Statistiques par groupes d’individus

Lorsque les individus sont naturellement organisés en groupes (par exemple femmes et hommes dans le fichier data_archeo.csv), afficher un résumé global du jeu de données peut ne pas être très informatif. Obtenir un résumé séparé pour chaque groupe d’individus serait plus pertinent, et permettrait de formuler quelques premières hypothèses.

Il existe de très nombreux moyens de réaliser cela avec R, mais en voici trois.

8.1 La combinaison split() + lapply()

Utilisant uniquement des fonctions R de base, cette combinaison est la manière historique de procéder en R (Wickham, 2011), et reste toujours efficace aujourd’hui.

La fonction split() permet de “casser” un dataframe en plusieurs entités selon les modalités de l’un de ses facteurs. Les différents dataframes ainsi obtenus sont stockés dans une liste.

La fonction lapply() permet quant à elle d’appliquer une même fonction à l’ensemble des éléments de cette liste.

On procède donc en commençant par “casser” le data frame originel pour obtenir séparément le dataframe des femmes et le dataframe des hommes :

sp <- split(dat, dat$Sexe)

Afin de visualiser l’objet sp ainsi obtenu et de bien vérifier qu’il s’agit d’une liste de deux dataframes, on pourra exécuter les instructions suivantes :

str(sp) # décrire le contenu de la liste sp
sp[[1]] # quelle est sa première composante ?
sp[[2]] # quelle est sa seconde composante ?

sp est donc bien une liste dont le premier élément est le dataframe des femmes, et le second élément est le dataframe des hommes. Pour les résumer tous les deux, on peut donc appliquer un summary() sur chaque élément de la liste sp :

lapply(sp, FUN = summary)
$F
 Site   Sexe        FM1             TM6             RM1        Hypoplasie
 A: 8   F:19   Min.   :393.7   Min.   :36.13   Min.   :207.3   Non:15    
 B:11   M: 0   1st Qu.:397.9   1st Qu.:42.33   1st Qu.:217.1   Oui: 4    
               Median :408.8   Median :44.01   Median :224.2             
               Mean   :414.2   Mean   :44.13   Mean   :222.8             
               3rd Qu.:429.5   3rd Qu.:46.74   3rd Qu.:228.5             
               Max.   :448.7   Max.   :49.27   Max.   :244.4             
               NA's   :2                       NA's   :1                 
 Presence_parure Orientation_corps
 Non: 7          Est  :2          
 Oui:12          Nord :2          
                 Ouest:8          
                 Sud  :7          
                                  
                                  
                                  

$M
 Site   Sexe        FM1             TM6             RM1        Hypoplasie
 A:13   F: 0   Min.   :407.4   Min.   :42.89   Min.   :220.7   Non:21    
 B:10   M:23   1st Qu.:426.5   1st Qu.:48.88   1st Qu.:235.5   Oui: 2    
               Median :443.9   Median :51.52   Median :242.3             
               Mean   :445.1   Mean   :51.40   Mean   :241.7             
               3rd Qu.:458.0   3rd Qu.:54.22   3rd Qu.:250.7             
               Max.   :508.9   Max.   :59.53   Max.   :257.1             
               NA's   :2                       NA's   :1                 
 Presence_parure Orientation_corps
 Non:19          Est  :13         
 Oui: 4          Nord : 6         
                 Ouest: 3         
                 Sud  : 1         
                                  
                                  
                                  

8.2 La fonction aggregate()

La fonction aggregate() prend en argument un dataframe, le divise en sous-groupes définis par un facteur, et applique une fonction (moyenne, écart-type, …) à chaque sous-groupe.

aggregate(num, FUN = mean, na.rm = TRUE,
          by = list(Sexe=dat$Sexe))
  Sexe      FM1      TM6      RM1
1    F 414.2482 44.12947 222.7994
2    M 445.0562 51.39609 241.7259

8.3 (Bonus) Utiliser {dplyr}

Sans trop détailler (car il ne s’agit pas ici d’une formation au “tidyverse” !), voici par exemple comment on procèderait pour obtenir la même table que ci-dessus en utilisant la syntaxe plus moderne introduite par {dplyr}.

dat |>
    select(Sexe, FM1, TM6, RM1) |>
    filter(! is.na(Sexe)) |>
    group_by(Sexe) |>
    summarise(across(FM1:RM1, \(x) mean(x, na.rm = TRUE)))
# A tibble: 2 × 4
  Sexe    FM1   TM6   RM1
  <fct> <dbl> <dbl> <dbl>
1 F      414.  44.1  223.
2 M      445.  51.4  242.

Notez l’usage du pipe |>, permettant d’enchaîner / de composer aisément plusieurs fonctions R. Vous pouvez par exemple vous référer à ce tutoriel pour en apprendre davantage sur les pipes en programmation.