7  Exploration et statistiques descriptives

7.1 Introduction

Les statistiques descriptives résument un jeu de données sans encore généraliser à une population plus large. Elles répondent à : combien ? quelle tendance ? quelle dispersion ? quelles associations apparentes ?

7.2 Objectifs pédagogiques

  • Calculer effectifs, tendances centrales et dispersion
  • Lire quantiles, distributions et tableaux croisés
  • Comparer des groupes
  • Calculer et interpréter une corrélation (sans causalité)
  • Éviter les erreurs d’interprétation courantes

7.3 Prérequis

  1. Notions de moyenne vues en Chapter 4.
library(tidyverse)
ventes <- read_csv("data/ventes.csv", show_col_types = FALSE) |>
  filter(!is.na(region), !is.na(quantite))
demo <- read_csv("data/demographie.csv", show_col_types = FALSE) |>
  filter(age >= 18, age <= 100, revenu_mensuel < 20000)

7.4 Analyse exploratoire (EDA)

L’EDA combine tableaux et graphiques pour comprendre la structure avant toute modélisation. Questions types : valeurs manquantes ? asymétrie ? groupes très différents ? relations linéaires ?

Vocabulaire
  • Tendance centrale : moyenne, médiane, mode
  • Dispersion : étendue, variance, écart-type, IQR
  • Distribution : comment les valeurs se répartissent
  • Corrélation : association linéaire entre deux variables quantitatives

7.5 Effectifs et fréquences

# Effectifs
table(ventes$region)
#> 
#>   Est  Nord Ouest   Sud 
#>    50    47    59    42
# Fréquences relatives
prop.table(table(ventes$region)) |> round(3)
#> 
#>   Est  Nord Ouest   Sud 
#> 0.253 0.237 0.298 0.212
ventes |> count(region, sort = TRUE) |>
  mutate(freq = n / sum(n))
#> # A tibble: 4 × 3
#>   region     n  freq
#>   <chr>  <int> <dbl>
#> 1 Ouest     59 0.298
#> 2 Est       50 0.253
#> 3 Nord      47 0.237
#> 4 Sud       42 0.212

7.6 Moyenne, médiane et mode

x <- ventes$montant
mean(x)
#> [1] 130.5734
median(x)
#> [1] 105.875
# Mode (valeur la plus fréquente) — pour variable discrète / qualitative
mode_stat <- function(v) {
  tb <- sort(table(v), decreasing = TRUE)
  names(tb)[1]
}
mode_stat(ventes$produit)
#> [1] "Marqueur"

Interprétation : si moyenne ≫ médiane, la distribution est souvent tirée vers la droite (quelques gros montants). La médiane est plus robuste aux extrêmes.

# Démonstration avec un extreme
y <- c(10, 12, 11, 13, 12, 200)
mean(y)
#> [1] 43
median(y)
#> [1] 12

7.7 Minimum, maximum, étendue

min(x); max(x); range(x)
#> [1] 3.72
#> [1] 483.2
#> [1]   3.72 483.20
diff(range(x))  # étendue
#> [1] 479.48

7.8 Quartiles et quantiles

quantile(x, probs = c(0, 0.25, 0.5, 0.75, 1))
#>      0%     25%     50%     75%    100% 
#>   3.720  42.535 105.875 196.185 483.200
IQR(x)  # Q3 - Q1
#> [1] 153.65
summary(x)
#>    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
#>    3.72   42.53  105.88  130.57  196.19  483.20

7.9 Variance et écart-type

var(x)   # variance
#> [1] 10963.07
sd(x)    # écart-type (même unité que x)
#> [1] 104.7047

L’écart-type mesure l’écart typique à la moyenne. Plus il est grand, plus les observations sont dispersées.

7.10 Distribution des variables

# Aperçu numérique
demo |>
  summarise(
    age_mean = mean(age),
    age_sd = sd(age),
    revenu_mean = mean(revenu_mensuel),
    revenu_sd = sd(revenu_mensuel),
    revenu_skew_approx = mean(revenu_mensuel) - median(revenu_mensuel)
  )
#> # A tibble: 1 × 5
#>   age_mean age_sd revenu_mean revenu_sd revenu_skew_approx
#>      <dbl>  <dbl>       <dbl>     <dbl>              <dbl>
#> 1     46.6   17.7       2180.      551.              -11.8

Histogrammes et densités seront détaillés en Chapter 8.

7.11 Comparaison de groupes

ventes |>
  group_by(region) |>
  summarise(
    n = n(),
    ca_moyen = mean(montant),
    ca_median = median(montant),
    ca_sd = sd(montant),
    .groups = "drop"
  )
#> # A tibble: 4 × 5
#>   region     n ca_moyen ca_median ca_sd
#>   <chr>  <int>    <dbl>     <dbl> <dbl>
#> 1 Est       50     143.     123.  120. 
#> 2 Nord      47     108.      62.8  98.2
#> 3 Ouest     59     129.     108.   92.2
#> 4 Sud       42     143.     112.  109.

Comparez toujours n, tendance centrale et dispersion : deux moyennes proches avec des écarts-types très différents ne racontent pas la même histoire.

7.12 Tableaux croisés

demo |>
  count(sexe, niveau_etudes) |>
  pivot_wider(names_from = sexe, values_from = n, values_fill = 0)
#> # A tibble: 5 × 3
#>   niveau_etudes Femme Homme
#>   <chr>         <int> <int>
#> 1 Autre            10     9
#> 2 Bac              18    20
#> 3 Doctorat          3     5
#> 4 Licence          26    33
#> 5 Master           12    12
# Avec proportions par ligne
tab <- table(demo$sexe, demo$niveau_etudes)
prop.table(tab, margin = 1) |> round(2)
#>        
#>         Autre  Bac Doctorat Licence Master
#>   Femme  0.14 0.26     0.04    0.38   0.17
#>   Homme  0.11 0.25     0.06    0.42   0.15

7.13 Corrélation entre variables

# Pearson (linéaire)
cor(demo$age, demo$revenu_mensuel, use = "complete.obs")
#> [1] 0.01489224
cor(mtcars$wt, mtcars$mpg)
#> [1] -0.8676594
mtcars |>
  select(mpg, wt, hp, disp) |>
  cor() |>
  round(2)
#>        mpg    wt    hp  disp
#> mpg   1.00 -0.87 -0.78 -0.85
#> wt   -0.87  1.00  0.66  0.89
#> hp   -0.78  0.66  1.00  0.79
#> disp -0.85  0.89  0.79  1.00
Corrélation ≠ causalité

Une corrélation forte indique une association statistique, pas qu’une variable cause l’autre. Un facteur tiers peut expliquer les deux.

7.14 Interprétation en langage courant

Exemple : cor(mtcars$wt, mtcars$mpg) est négatif et marqué.

Résultat observé : les voitures plus lourdes tendent à avoir une consommation en miles/gallon plus faible dans cet échantillon.

Interprétation prudente : il existe une association linéaire négative entre poids et mpg dans mtcars. Cela ne prouve pas, à elle seule, le mécanisme causal (moteur, aérodynamique, etc.).

7.15 Limites et erreurs d’interprétation

  1. Décrire un échantillon n’équivaut pas à conclure sur toute une population (→ inférence, Chapter 9).
  2. La moyenne seule cache multimodalité et outliers.
  3. Des catégories déséquilibrées faussent les lectures de proportions.
  4. Corréler deux séries temporelles sans précaution peut créer des artefacts.
  5. Multiplier les tris jusqu’à trouver un résultat « significatif » (data dredging).

7.16 Démonstration complète

set.seed(2024)
rapport <- list(
  ca_total = sum(ventes$montant),
  ca_moyen = mean(ventes$montant),
  ca_median = median(ventes$montant),
  top_produit = ventes |> count(produit, sort = TRUE) |> slice(1),
  cor_qte_montant = cor(ventes$quantite, ventes$montant)
)
rapport
#> $ca_total
#> [1] 25853.53
#> 
#> $ca_moyen
#> [1] 130.5734
#> 
#> $ca_median
#> [1] 105.875
#> 
#> $top_produit
#> # A tibble: 1 × 2
#>   produit      n
#>   <chr>    <int>
#> 1 Marqueur    43
#> 
#> $cor_qte_montant
#> [1] 0.6708037

7.17 Exercices

7.17.1 Niveau 1

  1. Calculez moyenne et médiane de demo$age.
  2. Affichez la table des effectifs de niveau_etudes.

7.17.2 Niveau 2

  1. Comparez le revenu moyen et médian par sexe.
  2. Calculez l’IQR de montant dans ventes.

7.17.3 Niveau 3

  1. Produisez un tableau région × produit avec le CA total (sum(montant)).
  2. Interprétez en une phrase cor(mtcars$hp, mtcars$mpg).

7.18 Corrections

mean(demo$age); median(demo$age)
#> [1] 46.64189
#> [1] 47
demo |> count(niveau_etudes, sort = TRUE)
#> # A tibble: 5 × 2
#>   niveau_etudes     n
#>   <chr>         <int>
#> 1 Licence          59
#> 2 Bac              38
#> 3 Master           24
#> 4 Autre            19
#> 5 Doctorat          8
demo |>
  group_by(sexe) |>
  summarise(moy = mean(revenu_mensuel), med = median(revenu_mensuel), .groups = "drop")
#> # A tibble: 2 × 3
#>   sexe    moy   med
#>   <chr> <dbl> <dbl>
#> 1 Femme 2204.  2215
#> 2 Homme 2159.  2146
IQR(ventes$montant)
#> [1] 153.65
ventes |>
  group_by(region, produit) |>
  summarise(ca = sum(montant), .groups = "drop") |>
  pivot_wider(names_from = produit, values_from = ca, values_fill = 0)
#> # A tibble: 4 × 6
#>   region Agenda Cahier Classeur Marqueur Stylo
#>   <chr>   <dbl>  <dbl>    <dbl>    <dbl> <dbl>
#> 1 Est     1757.  1443.    1228.    1418. 1295.
#> 2 Nord     282.  1560.    1201.     705. 1349.
#> 3 Ouest   1874.  1425.    1726.    1115. 1482.
#> 4 Sud      418.   934.     824.    2618. 1201.
cor(mtcars$hp, mtcars$mpg)
#> [1] -0.7761684
# Interprétation : association linéaire négative — plus de chevaux, mpg souvent plus faible dans cet échantillon.

7.19 Points clés

  • Décrire = résumer sans sur-interpréter.
  • Médiane et IQR sont robustes ; moyenne et écart-type sont sensibles aux extrêmes.
  • Toute corrélation demande une phrase de prudence sur la causalité.

7.20 Ressources

  • Çetinkaya-Rundel and Hardin (2023), Wickham, Çetinkaya-Rundel, and Grolemund (2023) (parties EDA)

7.21 Suite

Chapter 8 : donner forme visuelle à ces résumés avec ggplot2.