Lorsque vous analysez des données, la manière dont celles-ci sont structurées peut avoir un impact direct sur les résultats que vous allez présenter et la facilité avec laquelle vous allez obtenir ces résultats.
Il existe deux formats de données couramment utilisés : les formats “wide” et “long”. Il est essentiel de comprendre ces formats et de savoir comment passer de l’un à l’autre.
Dans cet article, je vous propose d’examiner ces deux formats de données, leurs avantages et inconvénients respectifs, et de vous montrer comment passer facilement de l’un à l’autre, à l’aide des fonctions pivot_longer
et pivot_wider
du package tidyr (appartient à tidyverse)
de R.
Le format de données “wide” est le format le plus courant pour stocker des données. Dans ce format, chaque variable est stockée dans une colonne distincte. Cela signifie que chaque observation est représentée par une seule ligne dans le jeu de données.
C’est par exemple le cas de données iris
nativement présentes dans R. Dans ce jeu de données, chaque ligne représente une fleur unique et les colonnes contiennent des valeurs distinctes pour chaque variable (longueur et largeur des sépales et pétales, ainsi que l’espèce de la fleur).
head(iris)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
6 5.4 3.9 1.7 0.4 setosa
D’ailleurs, pour mieux le comprendre, nous allons ajouter une colonne id
qui va servir à identifier chaque fleur :
library(tidyverse)
iris <- iris %>%
mutate(id = row_number()) %>%
select(id, everything() )
head(iris)
id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 1 5.1 3.5 1.4 0.2 setosa
2 2 4.9 3.0 1.4 0.2 setosa
3 3 4.7 3.2 1.3 0.2 setosa
4 4 4.6 3.1 1.5 0.2 setosa
5 5 5.0 3.6 1.4 0.2 setosa
6 6 5.4 3.9 1.7 0.4 setosa
Un autre cas d’utilisation typique du format wide est lorsque vous avez des mesures répétées sur des sujets dans des expériences médicales. Par exemple :
# Création du jeu de données en format wide
data_wide <- data.frame(
ID_Sujet = 1:4,
Tension_T0 = c(120, 130, 110, 140),
Tension_T3 = c(115, 128, 108, 135),
Tension_T6 = c(112, 125, 105, 132)
)
# Afficher le jeu de données
print(data_wide)
ID_Sujet Tension_T0 Tension_T3 Tension_T6
1 1 120 115 112
2 2 130 128 125
3 3 110 108 105
4 4 140 135 132
Le format long
est une autre manière de structurer les données où chaque observation est représentée par plusieurs lignes, une pour chaque variable.
Les données sont généralement organisées en trois colonnes principales : une pour l’identifiant de l’observation, une pour les variables, et une pour les valeurs. Par exemple, le format long des données iris est :
Le format long
peut sembler moins intuitif que le format wide
, mais il est souvent préféré pour l’analyse statistique et la visualisation des données, car il s’intègre mieux avec les outils de manipulation de données et les bibliothèques de visualisation en R.
Avantages :
Lisibilité : Le format wide est souvent plus intuitif et facile à lire pour des rapports ou des tableaux de bord. Chaque ligne représente une entité unique, et les colonnes montrent les différentes variables ou mesures associées à cette entité.
Comparaison directe : Il permet de comparer facilement les différentes mesures ou variables pour une même entité sur une seule ligne. Par exemple, dans notre jeu de données médicales, on peut facilement comparer la tension artérielle d’un sujet à différents moments.
Inconvénients :
ggplot2
, s’emploient avec des données en format long.
Travailler avec des données en format wide
peut donc nécessiter des étapes supplémentaires de transformation.wide
peut devenir très large, rendant le fichier difficile à gérer.Avantages :
ggplot2
et dplyr
. Scalabilité : Il est plus adapté aux jeux de données avec de nombreuses variables ou mesures répétées. Au lieu d’ajouter des colonnes, on ajoute des lignes, ce qui peut être plus facile à gérer.Inconvénients :
Complexité accrue : Il peut être moins intuitif et plus difficile à lire directement, car chaque mesure ou variable est représentée par plusieurs lignes. Cela peut rendre les tableaux de données longs et redondants.
Le choix entre le format wide
et le format long
dépend de l’objectif de votre analyse et des outils que vous utilisez. Si votre priorité est la présentation claire des données pour des rapports ou des tableaux de bord, le format wide est souvent plus adapté. En revanche, si vous effectuez des analyses statistiques complexes ou des visualisations, le format long sera généralement plus approprié.
Dans les sections suivantes, nous allons voir comment passer facilement du format wide
vers le format long
, et inversement, avec les fonctions pivot_longer()
et pivot_wider()
du package tidyr
de R.
Pour passer du format wide au format long en R, nous utilisons la fonction pivot_longer()
du package tidyr
. Cette fonction permet de rassembler plusieurs colonnes en une seule, en ajoutant des colonnes qui identifient les variables et leurs valeurs correspondantes.
Voici un exemple pratique utilisant notre jeu de données médicales initialement en format wide (voir le code de création plus haut) :
# Charger le package nécessaire
library(tidyr)
# Convertir le jeu de données du format wide au format long
data_long <- data_wide %>%
pivot_longer(
cols = Tension_T0:Tension_T6,
names_to = "Temps",
values_to = "Tension"
)
Explications :
pivot_longer
: Cette fonction permet de convertir plusieurs colonnes en deux colonnes une pour les noms des anciennes colonnes (Temps
) et une autre pour leurs valeurs respectives (Tension
).
cols = Tension_T0:Tension_T6
: Cette option spécifie les colonnes que nous souhaitons convertir. Ici, nous indiquons que nous voulons convertir toutes les colonnes de Tension_T0 à Tension_T6. Cela signifie que toutes les colonnes entre (et incluant) Tension_T0 et Tension_T6 seront regroupées dans les nouvelles colonnes Temps
et Tension
.
names_to = "Temps"
: Cette option crée une nouvelle colonne appelée Temps
qui contiendra les noms des colonnes d’origine (Tension_T0, Tension_T3, Tension_T6). Chaque valeur de la colonne Temps indiquera à quel moment la mesure a été prise.
values_to = "Tension"
: Cette option crée une nouvelle colonne appelée Tension
qui contiendra les valeurs des colonnes d’origine. Chaque valeur de la colonne Tension
correspondra à la mesure de tension artérielle pour chaque sujet à chaque moment indiqué dans la colonne Temps.
# affichage des données long
data_long
# A tibble: 12 × 3
ID_Sujet Temps Tension
<int> <chr> <dbl>
1 1 Tension_T0 120
2 1 Tension_T3 115
3 1 Tension_T6 112
4 2 Tension_T0 130
5 2 Tension_T3 128
6 2 Tension_T6 125
7 3 Tension_T0 110
8 3 Tension_T3 108
9 3 Tension_T6 105
10 4 Tension_T0 140
11 4 Tension_T3 135
12 4 Tension_T6 132
Pour passer du format long
au format wide
en R, nous utilisons la fonction pivot_wider()
du package tidyr.
Cette fonction permet de répartir une colonne de valeurs en plusieurs colonnes, en fonction des niveaux d’une colonne de clés.
Voici un exemple pratique utilisant notre jeu de données médicales en format long :
# Afficher le jeu de données long
print(data_long)
# A tibble: 12 × 3
ID_Sujet Temps Tension
<int> <chr> <dbl>
1 1 Tension_T0 120
2 1 Tension_T3 115
3 1 Tension_T6 112
4 2 Tension_T0 130
5 2 Tension_T3 128
6 2 Tension_T6 125
7 3 Tension_T0 110
8 3 Tension_T3 108
9 3 Tension_T6 105
10 4 Tension_T0 140
11 4 Tension_T3 135
12 4 Tension_T6 132
# Convertir le jeu de données du format long au format wide
new_data_wide <- data_long %>%
pivot_wider(
names_from = Temps,
values_from = Tension
)
Explications :
pivot_wider
: La fonction pivot_wider()
est utilisée pour convertir des colonnes de valeurs en plusieurs colonnes distinctes.
names_from = Temps
: Cette option indique que les noms des nouvelles colonnes seront tirés des valeurs de la colonne Temps. Les différents niveaux de la colonne Temps (Tension_T0, Tension_T3, Tension_T6) deviendront les noms des nouvelles colonnes.
values_from = Tension
: Cette option spécifie que les valeurs des nouvelles colonnes seront tirées de la colonne Tension.
# Afficher le jeu de données wide
print(new_data_wide)
# A tibble: 4 × 4
ID_Sujet Tension_T0 Tension_T3 Tension_T6
<int> <dbl> <dbl> <dbl>
1 1 120 115 112
2 2 130 128 125
3 3 110 108 105
4 4 140 135 132
Comme expliqué précédemment, le format long
est particulièrement adapté pour l’utilisation avec les fonctions du package dplyr
. Dans l’exemple ci-dessous, j’utilise le format long pour créer facilement une table descriptive. En regroupant les données par la variable Temps (à. l’aide de la fonction group_by()
, il est facile de calculer des statistiques descriptives telles que la moyenne, la médiane et l’écart-type de la tension artérielle pour chaque moment :
# Charger les packages nécessaires
library(dplyr)
# Afficher le jeu de données long
print(data_long)
# A tibble: 12 × 3
ID_Sujet Temps Tension
<int> <chr> <dbl>
1 1 Tension_T0 120
2 1 Tension_T3 115
3 1 Tension_T6 112
4 2 Tension_T0 130
5 2 Tension_T3 128
6 2 Tension_T6 125
7 3 Tension_T0 110
8 3 Tension_T3 108
9 3 Tension_T6 105
10 4 Tension_T0 140
11 4 Tension_T3 135
12 4 Tension_T6 132
# Créer une table descriptive
table_descriptive <- data_long %>%
group_by(Temps) %>%
summarise(
Moyenne = mean(Tension),
Mediane = median(Tension),
EcartType = sd(Tension)
)
# Afficher la table descriptive
print(table_descriptive)
# A tibble: 3 × 4
Temps Moyenne Mediane EcartType
<chr> <dbl> <dbl> <dbl>
1 Tension_T0 125 125 12.9
2 Tension_T3 122. 122. 12.2
3 Tension_T6 118. 118.
Le format long est particulièrement nécessaire pour créer des visualisations complexes avec ggplot2
, comme les spaghetti plots (ou fagot plots), qui permettent de visualiser les trajectoires individuelles au fil du temps.
En format long, chaque mesure de tension artérielle pour chaque sujet à chaque moment est représentée par une ligne distincte, avec Temps
indiquant le moment de la mesure et Tension
la valeur mesurée. Cela permet à ggplot2 de traiter et de visualiser facilement ces informations, car il peut utiliser la colonne Temps
pour l’axe x et la colonne Tension
pour l’axe y, tout en groupant les données par sujet pour tracer les lignes correspondantes. Cela n’aurait pas été possible de manière aussi simple et flexible avec des données en format wide.
library(ggplot2)
ggplot(data_long, aes(x = Temps, y = Tension, group = ID_Sujet, color = as.factor(ID_Sujet))) +
geom_line() +
geom_point() +
labs(title = "Changements de Tension Artérielle au Fil du Temps",
x = "Temps",
y = "Tension Artérielle",
color = "ID Sujet") +
theme_minimal()
Explications :
aes(x = Temps, y = Tension, group = ID_Sujet, color = as.factor(ID_Sujet))
: Définit les axes x et y, groupe les lignes par sujet, et colore les lignes en fonction des sujets.geom_line()
: Ajoute des lignes pour représenter les trajectoires individuelles.geom_point()
: Ajoute des points pour chaque mesure individuelle.labs
et theme_minimal()
: Personnalise les labels et applique un thème minimaliste pour améliorer la lisibilité.Le format long permet également d’utiliser facilement la fonction facet_wrap()
pour représenter plusieurs variables sur différents sous-graphiques.
Cela est particulièrement utile pour explorer et comparer des distributions de variables multiples. Voici un exemple utilisant le jeu de données iris pour créer des boxplots pour chaque variable mesurée, facettés par variable :
iris_long <- iris %>%
pivot_longer(cols = Sepal.Length : Petal.Width,
names_to = "Variable",
values_to = "Value")
print(head(iris_long))
# A tibble: 6 × 4
id Species Variable Value
<int> <fct> <chr> <dbl>
1 1 setosa Sepal.Length 5.1
2 1 setosa Sepal.Width 3.5
3 1 setosa Petal.Length 1.4
4 1 setosa Petal.Width 0.2
5 2 setosa Sepal.Length 4.9
6 2 setosa Sepal.Width 3
# Boxplots par variable
ggplot(iris_long, aes(y=Value, x=Species, colour=Species)) +
geom_jitter(height=0, width=0.15) +
geom_boxplot(alpha=0)+
facet_wrap(~Variable, scales="free_y") +
theme_minimal()
La fonction facet_wrap(~Variable, scales = "free_y")
crée des sous-graphiques pour chaque variable (longueur et largeur des sépales et pétales). Les échelles y indépendantes pour chaque sous-graphe grâce à l’argument scales = "free_y"
Par exemple, le format long, est nécessaire pour pouvoir réaliser une ANOVA sur mesure répétées avec la fonction aov()
. Voici un exemple avec nos données médicales :
# Effectuer une ANOVA sur mesures répétées
anova_result <- aov(Tension ~ Temps + Error(ID_Sujet/Temps), data = data_long)
summary(anova_result)
Error: ID_Sujet
Df Sum Sq Mean Sq F value Pr(>F)
Residuals 1 240 240
Error: ID_Sujet:Temps
Df Sum Sq Mean Sq
Temps 2 70.56 35.28
Error: Within
Df Sum Sq Mean Sq F value Pr(>F)
Temps 2 14.1 7.06 0.037 0.964
Residuals 6 1158.0 193.00
Ici, le format long est indispensable pour la ligne de commande aov(Tension ~ Temps + Error(ID_Sujet/Temps), data = data_long)
car il permet de structurer les données de manière à ce que les dépendances entre les mesures répétées soient explicitement représentées. Cela permet de spécifier correctement le modèle statistique et de tenir compte des variations entre et au sein des sujets, ce qui est essentiel pour une ANOVA à mesures répétées.
Si vous souhaitez en savoir plus sur l’utilisation des fonctions pivot_wider()
et pivot_longer()
, vous pouvez consulter la vignette dédiée à ces fonction, en copiant collant la comande suivante dans la console : vignette("pivot")
vignette("pivot")
Dans cet article, nous avons exploré les formats de données wide et long, et appris comment passer facilement d’un format à l’autre en utilisant les fonctions pivot_longer()
et pivot_wider()
du package tidyr
en R.
Nous avons vu que le format wide est particulièrement adapté pour la présentation des données et les comparaisons directes entre différentes mesures pour une même entité, tandis que le format long est plus flexible pour les analyses statistiques et les visualisations complexes.
N’hésitez pas à laisser un commentaire ci-dessous pour partager vos expériences, poser des questions ou proposer des améliorations. Vos commentaires sont précieux et m’aident à améliorer continuellement mes articles et tutoriels pour mieux répondre à vos besoins.
Retrouver le planning et les programmes de mes formations ici 👇👇👇
Retrouver mes propositions de services ici 👇👇👇
C’est possible en faisant un don sur la page Tipeee du blog
Enregistrez vous pour recevoir gratuitement mes fiches “aide mémoire” (ou cheat sheets) qui vous permettront de réaliser facilement les principales analyses biostatistiques avec le logiciel R et pour être informés des mises à jour du site.
13 Responses
Merci beaucoup
Ce blog vient à point nommé.
Merci pour le partage .
Très intéressant et je dirai même wahooooo
Cordialement
Merci beaucoup Claire ! 😊
C’est un récapitulatif très précis que je n’aurais pas aussi bien formulé alors que j’utilise souvent ces 2 super fonctions (pas faciles à expliquer aux autres 😬).
Alors que je fais l’essentiel de mes calculs et valorisations avec le format LONG, WIDE est utile pour préparer les calculs tels ACP (notamment pour une entrée dans l’outil factoMineR).
Bonjour Sonia,
L’ACP est un très bon exemple du format wide, je n’y avais pas pensé. Merci !
Magnifique. Ceci renforce mes compétences.
bonjour
Les fonctions pivots ne fonctionnent pas avec les données sous format texte.
j’ai eu un problème pour élargir un tableau d’adresses
je m’en suis sorti avec une boucle for et je me demandais s’il n’existait pas une jolie fonction qui fera le travail en 2 lignes plutôt qu’en 20…
bonne journée
laurent
Bonjour Laurent,
est-ce que vous pouvez, s’il vous plait, réaliser un petit exemple pour que je comprenne bien ?
J’essaierai de vous apporter une réponse.
Merci pour cet article !
Je ne connaissais pas cette fonctionnalité.
Grâce à votre article, fini le temps perdu à trouver des voies tortueuses pour produire certains graphiques.
Excellente initiative qui me convainc de remplacer les “spread” et autre “gather” pas aussi explicites et moins riches que ces “pivot…”
Bonjour Gilles,
oui effectivement les fonctions ont changé et se sont bien simplifiées.
Merci pour ce document édifiant.
C’est génial !
Merci pour ce document.