install.packages("skimr")De belles statistiques descriptives en R avec skimr
Un seul appel skim() pour un résumé riche et lisible de n’importe quel data frame
Apprenez à résumer un data frame en R avec skimr — la fonction skim() donne des résumés par type, le nombre de valeurs manquantes, des quantiles et des histogrammes en ligne dans un seul tableau lisible. Un meilleur str() et summary() pour l’exploration de données.
- Un seul appel —
skim(df)renvoie un résumé riche et lisible de n’importe quel data frame. - Des sections par type — les colonnes numériques, facteurs, caractères, dates et logiques reçoivent chacune les statistiques qui leur conviennent.
- Ce que
summary()ne vous a jamais dit — le nombre de valeurs manquantes, le taux de complétude et un spark-histogramme en ligne pour chaque colonne numérique. - Résumés par groupe, statistiques personnalisées et usage dans un pipeline — plus comment retirer les petits histogrammes quand votre police ne sait pas les afficher.
Vous venez de charger un nouveau data frame. Avant de modéliser ou de tracer quoi que ce soit, vous devez le voir : combien de lignes, quelles colonnes sont numériques plutôt que catégorielles, où se cachent les valeurs manquantes et à quoi ressemble grossièrement chaque distribution. En R base, cela veut dire plisser les yeux sur str() pour les types et sur summary() pour les statistiques — deux sorties, aucune complète. skimr condense tout cela en un seul tableau lisible.
Voyez skim() comme un meilleur str() et summary() réunis en un — il présente chaque type de variable séparément, ajoute les colonnes que ces fonctions de base omettent (valeurs manquantes, taux de complétude, écart-type, un jeu complet de quantiles) et affiche un minuscule spark-histogramme pour évaluer d’un coup d’œil la forme de chaque colonne numérique.
Installer et charger skimr
skimr est sur le CRAN ; une seule installation suffit :
Puis chargez-le dans votre session :
library(skimr)Résumer un data frame entier
Pointez skim() sur n’importe quel data frame et il fait le reste. Nous utiliserons le jeu de données intégré iris (150 fleurs, quatre mesures numériques plus le facteur Species) :
library(skimr)
skim(iris)| Name | iris |
| Number of rows | 150 |
| Number of columns | 5 |
| _______________________ | |
| Column type frequency: | |
| factor | 1 |
| numeric | 4 |
| ________________________ | |
| Group variables | None |
Variable type: factor
| skim_variable | n_missing | complete_rate | ordered | n_unique | top_counts |
|---|---|---|---|---|---|
| Species | 0 | 1 | FALSE | 3 | set: 50, ver: 50, vir: 50 |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| Sepal.Length | 0 | 1 | 5.84 | 0.83 | 4.3 | 5.1 | 5.80 | 6.4 | 7.9 | ▆▇▇▅▂ |
| Sepal.Width | 0 | 1 | 3.06 | 0.44 | 2.0 | 2.8 | 3.00 | 3.3 | 4.4 | ▁▆▇▂▁ |
| Petal.Length | 0 | 1 | 3.76 | 1.77 | 1.0 | 1.6 | 4.35 | 5.1 | 6.9 | ▇▁▆▇▂ |
| Petal.Width | 0 | 1 | 1.20 | 0.76 | 0.1 | 0.3 | 1.30 | 1.8 | 2.5 | ▇▁▇▅▃ |
Lisez la sortie de haut en bas. Elle commence par un Data Summary — 150 lignes, 5 colonnes — puis répartit les variables par type : un bloc pour l’unique colonne factor et un pour les quatre colonnes numeric. Cette répartition par type est tout l’intérêt : un facteur et une mesure numérique appellent des statistiques différentes, et skim() montre à chacun les bonnes.
Pour le facteur Species, vous obtenez n_missing, complete_rate, s’il est ordered, le nombre de niveaux uniques (n_unique = 3) et top_counts — ici, chacune des trois espèces apparaît 50 fois. Pour les colonnes numériques, vous obtenez la moyenne, l’écart-type, les cinq quantiles (p0, p25, p50, p75, p100) et une colonne hist — les petites barres unicode qui esquissent la distribution de chaque variable. iris n’a aucune valeur manquante, donc chaque complete_rate affiche 1.
Ce seul tableau répond à « quelles sont ces données ? » plus vite que n’importe quelle combinaison de fonctions de base.
Sélectionner des colonnes précises
Passez des noms de colonnes après le data frame pour ne résumer que celles-ci — pratique quand un tableau large déborderait sinon de l’écran :
library(skimr)
skim(iris, Sepal.Length, Petal.Length)| Name | iris |
| Number of rows | 150 |
| Number of columns | 5 |
| _______________________ | |
| Column type frequency: | |
| numeric | 2 |
| ________________________ | |
| Group variables | None |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| Sepal.Length | 0 | 1 | 5.84 | 0.83 | 4.3 | 5.1 | 5.80 | 6.4 | 7.9 | ▆▇▇▅▂ |
| Petal.Length | 0 | 1 | 3.76 | 1.77 | 1.0 | 1.6 | 4.35 | 5.1 | 6.9 | ▇▁▆▇▂ |
Vous obtenez le même bloc numérique, restreint aux deux colonnes demandées. La sélection s’appuie sur tidyselect, donc des utilitaires comme starts_with("Sepal") fonctionnent ici aussi.
Résumer par groupe
skim() respecte le groupement. Groupez d’abord les données et vous obtenez le résumé complet par type répété pour chaque groupe — le moyen le plus rapide de comparer des distributions selon une variable catégorielle. Le groupement provient de dplyr::group_by(), chargez donc dplyr en plus de skimr :
library(skimr)
library(dplyr)
iris |>
group_by(Species) |>
skim()| Name | group_by(iris, Species) |
| Number of rows | 150 |
| Number of columns | 5 |
| _______________________ | |
| Column type frequency: | |
| numeric | 4 |
| ________________________ | |
| Group variables | Species |
Variable type: numeric
| skim_variable | Species | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Sepal.Length | setosa | 0 | 1 | 5.01 | 0.35 | 4.3 | 4.80 | 5.00 | 5.20 | 5.8 | ▃▂▇▃▁ |
| Sepal.Length | versicolor | 0 | 1 | 5.94 | 0.52 | 4.9 | 5.60 | 5.90 | 6.30 | 7.0 | ▂▇▆▃▃ |
| Sepal.Length | virginica | 0 | 1 | 6.59 | 0.64 | 4.9 | 6.23 | 6.50 | 6.90 | 7.9 | ▁▃▇▃▂ |
| Sepal.Width | setosa | 0 | 1 | 3.43 | 0.38 | 2.3 | 3.20 | 3.40 | 3.68 | 4.4 | ▁▃▇▅▂ |
| Sepal.Width | versicolor | 0 | 1 | 2.77 | 0.31 | 2.0 | 2.52 | 2.80 | 3.00 | 3.4 | ▁▅▆▇▂ |
| Sepal.Width | virginica | 0 | 1 | 2.97 | 0.32 | 2.2 | 2.80 | 3.00 | 3.18 | 3.8 | ▂▆▇▅▁ |
| Petal.Length | setosa | 0 | 1 | 1.46 | 0.17 | 1.0 | 1.40 | 1.50 | 1.58 | 1.9 | ▁▃▇▃▁ |
| Petal.Length | versicolor | 0 | 1 | 4.26 | 0.47 | 3.0 | 4.00 | 4.35 | 4.60 | 5.1 | ▂▂▇▇▆ |
| Petal.Length | virginica | 0 | 1 | 5.55 | 0.55 | 4.5 | 5.10 | 5.55 | 5.88 | 6.9 | ▃▇▇▃▂ |
| Petal.Width | setosa | 0 | 1 | 0.25 | 0.11 | 0.1 | 0.20 | 0.20 | 0.30 | 0.6 | ▇▂▂▁▁ |
| Petal.Width | versicolor | 0 | 1 | 1.33 | 0.20 | 1.0 | 1.20 | 1.30 | 1.50 | 1.8 | ▅▇▃▆▁ |
| Petal.Width | virginica | 0 | 1 | 2.03 | 0.27 | 1.4 | 1.80 | 2.00 | 2.30 | 2.5 | ▂▇▆▅▇ |
Désormais, chaque statistique numérique — moyenne, écart-type, quantiles et spark-histogramme — est ventilée par espèce. Comparez les lignes Petal.Length entre les trois groupes et la séparation entre espèces saute immédiatement aux yeux, histogramme compris.
Personnaliser les statistiques
Les statistiques par défaut sont raisonnables, mais vous pouvez construire votre propre skimmer avec skim_with(). Vous fournissez une liste de fonctions nommées par type de données à l’aide de sfl() (une « skimr function list ») ; mettez append = FALSE pour remplacer les valeurs par défaut au lieu de les compléter :
library(skimr)
my_skim <- skim_with(
numeric = sfl(
iqr = IQR,
mad = mad,
p99 = ~ quantile(., probs = 0.99)
),
append = FALSE
)
my_skim(iris, Sepal.Length)| Name | iris |
| Number of rows | 150 |
| Number of columns | 5 |
| _______________________ | |
| Column type frequency: | |
| numeric | 1 |
| ________________________ | |
| Group variables | None |
Variable type: numeric
| skim_variable | n_missing | complete_rate | iqr | mad | p99 |
|---|---|---|---|---|---|
| Sepal.Length | 0 | 1 | 1.3 | 1.04 | 7.7 |
skim_with() renvoie une nouvelle fonction (my_skim ici) qui se comporte comme skim() mais rapporte exactement les statistiques que vous avez définies — l’écart interquartile, la médiane des écarts absolus et un 99e percentile personnalisé via une formule unilatérale. Réutilisez my_skim() sur n’importe quel data frame pour obtenir ce même résumé sur mesure à chaque fois.
Utiliser la sortie de skim() dans un pipeline
skim() renvoie un skim_df — un tibble sous le capot — ses résultats s’intègrent donc directement dans un pipeline tidyverse. Filtrez, triez ou sélectionnez le résumé comme n’importe quel data frame. Par exemple, extrayez uniquement les variables numériques et gardez les colonnes qui vous intéressent :
library(skimr)
library(dplyr)
skim(iris) |>
filter(skim_type == "numeric") |>
select(skim_variable, numeric.mean, numeric.sd)# A tibble: 4 × 3
skim_variable numeric.mean numeric.sd
<chr> <dbl> <dbl>
1 Sepal.Length 5.84 0.828
2 Sepal.Width 3.06 0.436
3 Petal.Length 3.76 1.77
4 Petal.Width 1.20 0.762
Comme le résumé est une donnée, vous pouvez l’injecter dans un rapport, un tableau gt ou un calcul ultérieur, au lieu de seulement le lire sur la console. skimr fournit aussi yank() pour récupérer le bloc d’un seul type et partition() pour scinder le résumé en une liste par type.
Retirer les histogrammes quand votre police ne sait pas les afficher
La colonne hist utilise des caractères de bloc unicode pour dessiner ses spark-histogrammes. C’est superbe dans une console moderne, mais cela peut s’afficher sous forme de carrés ou de points d’interrogation dans certains pipelines PDF, fichiers de log ou polices. Le cas échéant, utilisez skim_without_charts() pour un tableau propre et compatible ASCII :
library(skimr)
skim_without_charts(iris)| Name | iris |
| Number of rows | 150 |
| Number of columns | 5 |
| _______________________ | |
| Column type frequency: | |
| factor | 1 |
| numeric | 4 |
| ________________________ | |
| Group variables | None |
Variable type: factor
| skim_variable | n_missing | complete_rate | ordered | n_unique | top_counts |
|---|---|---|---|---|---|
| Species | 0 | 1 | FALSE | 3 | set: 50, ver: 50, vir: 50 |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 |
|---|---|---|---|---|---|---|---|---|---|
| Sepal.Length | 0 | 1 | 5.84 | 0.83 | 4.3 | 5.1 | 5.80 | 6.4 | 7.9 |
| Sepal.Width | 0 | 1 | 3.06 | 0.44 | 2.0 | 2.8 | 3.00 | 3.3 | 4.4 |
| Petal.Length | 0 | 1 | 3.76 | 1.77 | 1.0 | 1.6 | 4.35 | 5.1 | 6.9 |
| Petal.Width | 0 | 1 | 1.20 | 0.76 | 0.1 | 0.3 | 1.30 | 1.8 | 2.5 |
Même résumé, sans spark-histogrammes — idéal pour un rendu en PDF ou pour alimenter des rapports en texte brut.
Foire aux questions
summary() affiche un ensemble compact de statistiques avec tous les types de variables mélangés et ne vous donne ni le nombre de valeurs manquantes ni l’écart-type. skim() présente chaque type de variable séparément (numérique, facteur, caractère, date, logique), ajoute n_missing, complete_rate et sd, montre un jeu complet de quantiles et dessine un spark-histogramme en ligne pour chaque colonne numérique. Il renvoie aussi le résultat sous forme de data frame que vous pouvez enchaîner dans un pipeline — ce que summary() ne fait pas.
Groupez les données avec dplyr::group_by() avant d’appeler skim() : iris |> dplyr::group_by(Species) |> skim(). skim() détecte le groupement et répète le résumé complet par type une fois pour chaque groupe, ce qui vous permet de comparer moyennes, dispersions et formes de distribution entre les niveaux d’une variable catégorielle.
La colonne hist est dessinée avec des caractères de bloc unicode. Si votre police, votre moteur PDF ou votre visionneuse de logs ne sait pas les afficher, ils se dégradent en carrés ou en ?. Appelez skim_without_charts() pour le même résumé sans les spark-histogrammes, ou passez à une console ou une police avec un support unicode complet.
Oui. skim() renvoie un skim_df, qui est un tibble, vous pouvez donc le filter(), select(), arrange() ou mutate() comme n’importe quel data frame — par exemple, skim(iris) |> dplyr::filter(skim_type == "numeric"). Utilisez yank() pour extraire le bloc d’un seul type ou partition() pour scinder le résumé en une liste par type.
Construisez un skimmer personnalisé avec skim_with(), en lui passant une liste sfl() de fonctions nommées par type de données : skim_with(numeric = sfl(iqr = IQR), append = FALSE). Il renvoie une nouvelle fonction que vous appelez exactement comme skim(). Mettez append = TRUE pour ajouter vos statistiques par-dessus les valeurs par défaut, ou FALSE pour les remplacer entièrement.
Pour aller plus loin dans /learn
skim(), c’est là que l’exploration de données commence — l’étape suivante consiste à visualiser ce qu’elle révèle. Pour les tutoriels complets, sous contrôle de reproductibilité :
- ggplot2 en R — transformez les distributions qu’esquisse
skim()en figures prêtes à publier. - Visualisation de données — le pilier complet, du premier graphique au rendu final.
À voir aussi
- ggplot2 en R — la série de visualisation. · Visualisation de données — le hub du pilier.
Demandez à Prova « résume mon data frame avec skim et dis-moi quelles colonnes ont des valeurs manquantes » — elle répond avec du code que vous pouvez exécuter sur vos propres données. The runtime is the judge. Demander à Prova →
Citation
@online{kassambara2026,
author = {Kassambara, Alboukadel},
title = {De belles statistiques descriptives en R avec skimr},
date = {2026-07-08},
url = {https://www.datanovia.com/blog/skimr-summary-statistics-in-r},
langid = {fr}
}