Exercices pratiques

Approfondissement en analyse de données avec R — FSS, Université Laval

Auteur·rice

Adrien Cloutier

Suite de : Initiation à l’analyse de données avec R — Les exercices de base (filter, select, group_by, ggplot2 intro) sont disponibles sur le site du premier atelier. Les exercices ci-dessous reprennent là où ce premier atelier s’est arrêté.

1 Mise en place

Avant de commencer, chargez les packages nécessaires :

library(tidyverse)
library(gapminder)
library(tidytext)
library(wordcloud)
library(modelsummary)

Les données Gapminder contiennent des informations sur 142 pays de 1952 à 2007 (toutes les 5 ans) :

glimpse(gapminder)

2 Section 1 : ggplot2

2.1 Exercice 1.1 — facet_wrap() : petits multiples

facet_wrap() crée un graphique séparé pour chaque valeur d’une variable — très utile pour comparer des sous-groupes.

Créez un nuage de points (PIB per capita en X, espérance de vie en Y) pour 2007, avec :

  • Échelle X logarithmique
  • Un facet par continent (facet_wrap(~ continent))
  • Points colorés en bleu (#003875), transparence 0.6
  • Titre et étiquettes d’axes
gapminder |>
  filter(???) |>
  ggplot(aes(x = ???, y = ???)) +
  geom_point(color = "#003875", alpha = 0.6) +
  scale_x_log10() +
  facet_wrap(~ ???) +
  labs(???) +
  theme_minimal()
gapminder |>
  filter(year == 2007) |>
  ggplot(aes(x = gdpPercap, y = lifeExp)) +
  geom_point(color = "#003875", alpha = 0.6) +
  scale_x_log10() +
  facet_wrap(~ continent) +
  labs(
    title = "PIB per capita et espérance de vie par continent (2007)",
    x     = "PIB per capita (échelle log)",
    y     = "Espérance de vie (années)"
  ) +
  theme_minimal()

2.2 Exercice 1.2 — Évolution dans le temps

Tracez l’évolution de l’espérance de vie moyenne par continent de 1952 à 2007. Utilisez geom_line() avec une ligne par continent.

Astuce : Calculez d’abord la moyenne avec group_by() + summarise(), puis passez le résultat à ggplot.

# Votre code ici
gapminder |>
  group_by(???) |>
  summarise(???) |>
  ggplot(aes(x = year, y = ???, color = continent)) +
  geom_line(linewidth = 1) +
  labs(???) +
  theme_minimal()
gapminder |>
  group_by(continent, year) |>
  summarise(esperance_moy = mean(lifeExp), .groups = "drop") |>
  ggplot(aes(x = year, y = esperance_moy, color = continent)) +
  geom_line(linewidth = 1) +
  labs(
    title = "Évolution de l'espérance de vie par continent (1952–2007)",
    x     = "Année",
    y     = "Espérance de vie moyenne (années)",
    color = "Continent"
  ) +
  theme_minimal()

2.3 Exercice 1.3 — Histogramme

Faites un histogramme de la distribution du PIB per capita en 2007.

  • Utilisez fill = continent pour colorer par continent
  • Ajoutez alpha = 0.6 pour la transparence
  • Appliquez scale_x_log10()
# Votre code ici
gapminder |>
  filter(year == 2007) |>
  ggplot(aes(x = gdpPercap, fill = continent)) +
  geom_histogram(bins = 30, alpha = 0.6) +
  scale_x_log10() +
  labs(
    title = "Distribution du PIB per capita par continent (2007)",
    x     = "PIB per capita (échelle log)",
    y     = "Nombre de pays",
    fill  = "Continent"
  ) +
  theme_minimal()

3 Section 2 : Analyse textuelle

3.1 Les données

reponses <- tibble(
  id     = 1:8,
  groupe = c("Centre", "Droite", "Centre", "Gauche",
             "Centre", "Droite", "Gauche", "Droite"),
  texte  = c(
    "The government must invest more in clean energy and protect the environment",
    "The cost of living crisis is terrible, prices are too high for working families",
    "Our healthcare system needs urgent reform and more funding immediately",
    "I appreciate the government's efforts on climate change and housing affordability",
    "Education should be free and accessible to all young people in this country",
    "The economy is struggling and the government has failed to address inflation",
    "We need stronger social programs and better support for vulnerable communities",
    "This government's terrible policies have destroyed our economic opportunities"
  )
)

3.2 Exercice 2.1 — stringr

Avec le data frame reponses :

  1. Créez une colonne nb_mots avec le nombre de mots dans chaque réponse (str_count(texte, "\\w+"))
  2. Créez une colonne mentionne_gouvernement (TRUE/FALSE) si "government" apparaît
  3. Filtrez pour garder seulement les réponses qui mentionnent "government"
# Votre code ici
reponses |>
  mutate(
    nb_mots                = str_count(???, "\\w+"),
    mentionne_gouvernement = str_detect(???, ???)
  ) |>
  filter(???)
reponses |>
  mutate(
    nb_mots                = str_count(texte, "\\w+"),
    mentionne_gouvernement = str_detect(texte, "government")
  ) |>
  filter(mentionne_gouvernement)

3.3 Exercice 2.2 — Fréquences de mots

  1. Tokenisez les réponses avec unnest_tokens()
  2. Enlevez les mots vides (anti_join avec stop_words)
  3. Comptez et visualisez les 10 mots les plus fréquents
# Étape 1 : tokeniser
mots <- reponses |>
  unnest_tokens(???, ???)

# Étape 2 : enlever les stop words
data(stop_words)

mots_propres <- mots |>
  anti_join(???, by = c(??? = "word"))

# Étape 3 : visualiser
mots_propres |>
  count(???, sort = TRUE) |>
  slice_head(n = 10) |>
  ggplot(aes(x = reorder(mot, n), y = n)) +
  geom_col(fill = "#003875") +
  coord_flip() +
  labs(title = "10 mots les plus fréquents", x = "Mot", y = "Fréquence") +
  theme_minimal()
mots <- reponses |>
  unnest_tokens(mot, texte)

data(stop_words)

mots_propres <- mots |>
  anti_join(stop_words, by = c("mot" = "word"))

mots_propres |>
  count(mot, sort = TRUE) |>
  slice_head(n = 10) |>
  ggplot(aes(x = reorder(mot, n), y = n)) +
  geom_col(fill = "#003875") +
  coord_flip() +
  labs(title = "10 mots les plus fréquents", x = "Mot", y = "Fréquence") +
  theme_minimal()

3.4 Exercice 2.3 — Analyse de sentiment par groupe

Calculez le score de sentiment net (positifs − négatifs) pour chaque groupe politique (Centre, Droite, Gauche) avec le lexique "bing". Visualisez le résultat sous forme de graphique en barres.

Rappel : Score net = nombre de mots positifs − nombre de mots négatifs

bing <- get_sentiments("bing")

mots_propres |>
  inner_join(???, by = c("mot" = "word")) |>
  count(???, sentiment) |>
  pivot_wider(names_from = sentiment, values_from = n, values_fill = 0) |>
  mutate(score_net = positive - negative) |>
  ggplot(aes(x = reorder(groupe, score_net), y = score_net, fill = score_net > 0)) +
  geom_col(show.legend = FALSE) +
  scale_fill_manual(values = c("firebrick", "#2ca25f")) +
  coord_flip() +
  labs(title = "Ton des réponses par groupe politique",
       x = "Groupe", y = "Score net (positifs − négatifs)") +
  theme_minimal()
bing <- get_sentiments("bing")

mots_propres |>
  inner_join(bing, by = c("mot" = "word")) |>
  count(groupe, sentiment) |>
  pivot_wider(names_from = sentiment, values_from = n, values_fill = 0) |>
  mutate(score_net = positive - negative) |>
  ggplot(aes(x = reorder(groupe, score_net), y = score_net, fill = score_net > 0)) +
  geom_col(show.legend = FALSE) +
  scale_fill_manual(values = c("firebrick", "#2ca25f")) +
  coord_flip() +
  geom_hline(yintercept = 0, linetype = "dashed") +
  labs(
    title    = "Ton des réponses par groupe politique",
    subtitle = "Score net = mots positifs − mots négatifs",
    x        = "Groupe",
    y        = "Score de sentiment net"
  ) +
  theme_minimal()

4 Section 3 : Régression linéaire

4.1 Exercice 3.1 — Régression simple

Avec les données Gapminder pour 2007 :

  1. Créez un sous-ensemble data_2007 filtré sur 2007, et ajoutez une colonne log_pib = log(gdpPercap)
  2. Faites une régression linéaire : lifeExp ~ log_pib
  3. Affichez le résumé avec summary()
  4. Interprétez : l’effet est-il statistiquement significatif? Positif ou négatif?
data_2007 <- gapminder |>
  filter(???) |>
  mutate(log_pib = log(???))

modele <- lm(???, data = data_2007)
summary(modele)
data_2007 <- gapminder |>
  filter(year == 2007) |>
  mutate(log_pib = log(gdpPercap))

modele <- lm(lifeExp ~ log_pib, data = data_2007)
summary(modele)

Interprétation : L’effet est positif et significatif (p < 0.001). Chaque augmentation d’une unité du log du PIB per capita est associée à ~7–8 ans de plus d’espérance de vie. R² ≈ 0.65.


4.2 Exercice 3.2 — Visualiser la droite de régression

Représentez graphiquement la relation entre log_pib et lifeExp avec :

  • geom_point() coloré par continent
  • geom_smooth(method = "lm") pour la droite de régression
data_2007 |>
  ggplot(aes(x = ???, y = ???)) +
  geom_point(aes(color = ???), alpha = 0.7) +
  geom_smooth(method = "lm", color = "black", se = TRUE) +
  labs(
    title = "Régression : log(PIB per capita) → Espérance de vie",
    x     = "Log du PIB per capita",
    y     = "Espérance de vie (années)",
    color = "Continent"
  ) +
  theme_minimal()
data_2007 |>
  ggplot(aes(x = log_pib, y = lifeExp)) +
  geom_point(aes(color = continent), alpha = 0.7) +
  geom_smooth(method = "lm", color = "black", se = TRUE) +
  labs(
    title = "Régression : log(PIB per capita) → Espérance de vie",
    x     = "Log du PIB per capita",
    y     = "Espérance de vie (années)",
    color = "Continent"
  ) +
  theme_minimal()

4.3 Exercice 3.3 — Régression multiple

Ajoutez pop comme deuxième prédicteur. Comparez les deux modèles avec modelsummary().

modele2 <- lm(lifeExp ~ log_pib + pop, data = data_2007)

modelsummary(
  list("Modèle 1" = modele, "Modèle 2" = modele2),
  stars = TRUE
)
modele2 <- lm(lifeExp ~ log_pib + pop, data = data_2007)

modelsummary(
  list("Modèle 1" = modele, "Modèle 2" = modele2),
  stars = TRUE
)

À observer : L’effet du log_pib reste stable entre les deux modèles. La population (pop) n’a pratiquement aucun effet sur l’espérance de vie une fois le PIB contrôlé.


Questions? adrien.cloutier.1@ulaval.ca