20  Échelles de Likert

Les échelles de Likert tirent leur nom du psychologue américain Rensis Likert qui les a développées. Elles sont le plus souvent utilisées pour des variables d’opinion. Elles sont codées sous forme de variable catégorielle et chaque item est codé selon une graduation comprenant en général cinq ou sept choix de réponse, par exemple : Tout à fait d’accord, D’accord, Ni en désaccord ni d’accord, Pas d’accord, Pas du tout d’accord.

Pour les échelles à nombre impair de choix, le niveau central permet d’exprimer une absence d’avis, ce qui rend inutile une modalité « Ne sait pas ». Les échelles à nombre pair de modalités voient l’omission de la modalité neutre et sont dites « à choix forcé ».

20.1 Exemple de données

Générons un jeu de données qui nous servira pour les différents exemples.

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.5.1     ✔ tibble    3.2.1
✔ lubridate 1.9.3     ✔ tidyr     1.3.1
✔ purrr     1.0.2     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(labelled)
niveaux <- c(
  "Pas du tout d'accord",
  "Plutôt pas d'accord",
  "Ni d'accord, ni pas d'accord",
  "Plutôt d'accord",
  "Tout à fait d'accord"
)
set.seed(42)
df <-
  tibble(
    groupe = sample(c("A", "B"), 150, replace = TRUE),
    q1 = sample(niveaux, 150, replace = TRUE),
    q2 = sample(niveaux, 150, replace = TRUE, prob = 5:1),
    q3 = sample(niveaux, 150, replace = TRUE, prob = 1:5),
    q4 = sample(niveaux, 150, replace = TRUE, prob = 1:5),
    q5 = sample(c(niveaux, NA), 150, replace = TRUE),
    q6 = sample(niveaux, 150, replace = TRUE, prob = c(1, 0, 1, 1, 0))
  ) |> 
  mutate(across(q1:q6, ~ factor(.x, levels = niveaux))) |> 
  set_variable_labels(
    q1 = "Première question",
    q2 = "Seconde question",
    q3 = "Troisième question",
    q4 = "Quatrième question",
    q5 = "Cinquième question",
    q6 = "Sixième question"
  )

20.2 Tableau de fréquence

On peut tout à fait réaliser un tableau de fréquence classique avec gtsummary::tbl_summary().

library(gtsummary)
df |> 
  tbl_summary(include = q1:q6)
Characteristic N = 1501
Première question
    Pas du tout d'accord 39 (26%)
    Plutôt pas d'accord 32 (21%)
    Ni d'accord, ni pas d'accord 25 (17%)
    Plutôt d'accord 30 (20%)
    Tout à fait d'accord 24 (16%)
Seconde question
    Pas du tout d'accord 56 (37%)
    Plutôt pas d'accord 44 (29%)
    Ni d'accord, ni pas d'accord 19 (13%)
    Plutôt d'accord 26 (17%)
    Tout à fait d'accord 5 (3.3%)
Troisième question
    Pas du tout d'accord 8 (5.3%)
    Plutôt pas d'accord 17 (11%)
    Ni d'accord, ni pas d'accord 29 (19%)
    Plutôt d'accord 43 (29%)
    Tout à fait d'accord 53 (35%)
Quatrième question
    Pas du tout d'accord 11 (7.3%)
    Plutôt pas d'accord 19 (13%)
    Ni d'accord, ni pas d'accord 31 (21%)
    Plutôt d'accord 40 (27%)
    Tout à fait d'accord 49 (33%)
Cinquième question
    Pas du tout d'accord 33 (26%)
    Plutôt pas d'accord 25 (20%)
    Ni d'accord, ni pas d'accord 28 (22%)
    Plutôt d'accord 25 (20%)
    Tout à fait d'accord 16 (13%)
    Unknown 23
Sixième question
    Pas du tout d'accord 50 (33%)
    Plutôt pas d'accord 0 (0%)
    Ni d'accord, ni pas d'accord 50 (33%)
    Plutôt d'accord 50 (33%)
    Tout à fait d'accord 0 (0%)
1 n (%)

Cependant, cela produit un tableau inutilement long, d’autant plus que les variables q1 à q6 ont les mêmes modalités de réponse. Le package bstfun propose une fonction expérimentale bstfun::tbl_likert() offrant un affichage plus compact.

Important

Ce package n’est pas disponible sur CRAN : il est donc nécessaire de l’installer depuis GitHub avec la commande suivante : remotes::install_github("MSKCC-Epi-Bio/bstfun"). Si vous êtes sous Windows, il vous faudra probablement installer au préalable RTools qui peut être téléchargé à l’adresse https://cran.r-project.org/bin/windows/Rtools/.

library(bstfun)

Attachement du package : 'bstfun'
L'objet suivant est masqué depuis 'package:gtsummary':

    trial
df |> 
  tbl_likert(
    include = q1:q6
  )
Characteristic Pas du tout d’accord1 Plutôt pas d’accord1 Ni d’accord, ni pas d’accord1 Plutôt d’accord1 Tout à fait d’accord1
Première question 39 (26%) 32 (21%) 25 (17%) 30 (20%) 24 (16%)
Seconde question 56 (37%) 44 (29%) 19 (13%) 26 (17%) 5 (3.3%)
Troisième question 8 (5.3%) 17 (11%) 29 (19%) 43 (29%) 53 (35%)
Quatrième question 11 (7.3%) 19 (13%) 31 (21%) 40 (27%) 49 (33%)
Cinquième question 33 (26%) 25 (20%) 28 (22%) 25 (20%) 16 (13%)
Sixième question 50 (33%) 0 (0%) 50 (33%) 50 (33%) 0 (0%)
1 n (%)

On peut utiliser add_n() pour ajouter les effectifs totaux et add_continuous_stat() pour ajouter une statistique continue en traitant la variable comme un score (ici nous allons attribuer les valeurs -2, -1, 0, +1 et +2).

df |> 
  tbl_likert(
    include = q1:q6,
    statistic = ~ "{p}%"
  ) |> 
  add_n() |> 
  add_continuous_stat(score_values = -2:2)
Characteristic N Pas du tout d’accord1 Plutôt pas d’accord1 Ni d’accord, ni pas d’accord1 Plutôt d’accord1 Tout à fait d’accord1 Mean
Première question 150 26% 21% 17% 20% 16% -0.21
Seconde question 150 37% 29% 13% 17% 3.3% -0.80
Troisième question 150 5.3% 11% 19% 29% 35% 0.77
Quatrième question 150 7.3% 13% 21% 27% 33% 0.65
Cinquième question 127 26% 20% 22% 20% 13% -0.27
Sixième question 150 33% 0% 33% 33% 0% -0.33
1 %

20.3 Représentations graphiques

À partir de sa version 0.3.0, le package ggstats propose une fonction ggstats::gglikert() pour représenter des données de Likert sous forme d’un diagramme en barre centré sur la modalité centrale.

library(ggstats)
gglikert(df, include = q1:q6)

Par défaut, les pourcentages totaux ne prennent pas en compte la modalité centrale (lorsque le nombre de modalité est impair). On peut inclure la modalité centrale avec totals_include_center = TRUE, auquel cas la modalité centrale seront comptabilisée pour moitié de chaque côté. Le paramètre sort permet de trier les modalités (voir l’aide de ggstats::gglikert() pour plus de détails sur les différentes méthodes de tri).

df |> 
  gglikert(
    include = q1:q6,
    totals_include_center = TRUE,
    sort = "ascending"
  ) +
  guides(
    fill = guide_legend(nrow = 2)
  )

Il est possible de séparer les résultats par sous-groupe avec des facettes.

df |> 
  gglikert(
    include = q1:q6,
    facet_cols = vars(groupe)
  )

df |> 
  gglikert(
    include = q1:q6,
    y = "groupe",
    facet_rows = vars(.question),
    facet_label_wrap = 15
  )

Une représentation alternative consiste à réaliser un graphique en barres classiques, ce que l’on peut aisément obtenir avec ggstats::gglikert_stacked().

df |>
  gglikert_stacked(
    include = q1:q6,
    sort = "ascending",
    add_median_line = TRUE
  )