Des données d’enquête aux premiers résultats

Une initiation à l’utilisation de R/RStudio à partir de l’enquête Envie

Claire Kersuzan (PUD-Bx, MSH-Bx/Univ. de Bordeaux, LifeObs/Ined)
Capucine Rauch (PUD-S, MISHA/Univ. de Strasbourg, LifeObs/Ined)
Maude Crouzet (SAGE/Univ. de Strasbourg)

Troisième partie

Mise en pratique

Reproduction d’un résultat scientifique

Objectifs de cette troisième partie

  • Mise en pratique des notions présentées précédemment
  • Reproduction d’un résultat scientifique

Graphique à reproduire

Description du graphique

  • Proportion de jeunes ayant été en couple dans l’année selon l’âge et l’origine sociale
  • Diagramme en barres
    • barres = catégories (âge, origine sociale) ;
    • longueur = pourcentage ;
    • couleur = groupes (femmes, hommes).

Derrière le graphique

Ingrédients et ustensiles

  • Dictionnaire des codes
  • Questionnaire
  • Fichier de données
  • Script R

Le projet RStudio contient tout ces éléments !

  • Des souvenirs d’hier

Les grandes étapes

  1. Sélectionner et préparer les variables

  2. Recoder certaines variables

  3. Calculer des tableaux croisés pondérés

  4. Mettre les résultats en forme

  5. Construire le graphique

C’est parti !

Préparation de l’environnement de travail

Créer un nouveau script dans le projet

  • Ouvrir le projet RStudio Envie.Rproj
  • Créer un nouveau script : FileNew FileR Script

Installer les packages

Charger les packages

library(readr) #importer les données au format .csv
library(questionr)#manipuler + traiter les données
library(tidyverse)#transformer + analyser les données
library(ggplot2) #réaliser des graphiques
library(esquisse) #créer facilement des graphiques

Importer les données

  • Format .csv → fonction read_csv() du package readr
ENVIE <- read_csv("data/Envie_FPA.csv")

Sélectionner et préparer les variables

De quelles variables avons-nous besoin ?

  • avoir été en couple au cours de l’année
  • genre (femmes et hommes)
  • âge
  • origine sociale
  • pondération

Comment s’appellent-elles ?

C’est le moment d’ouvrir le dictionnaire des codes !

  • avoir été en couple au cours de l’année : couple12M
  • genre : genre_id
  • âge : age_rec
  • origine sociale : par_men_5
  • pondération : poidscal

Sélection des variables

  • Nouvelle base ENVIE2 contenant uniquement les variables d’intérêt
  • select(BDD, var1, var2, ... , varN)
ENVIE2 <- select(ENVIE, genre_id, age_rec, par_men_5, couple12M, poidscal)

Exploration des variables d’intérêt

Comment se répartissent les individus dans les modalités des variables d’intérêt ?

  • Tris à plat
  • table(BDD$var,useNA="always")
  • Identité de genre
table(ENVIE2$genre_id,useNA="always")

   1    2    3 <NA> 
5246 4657  118    0 

À vous de jouer, réalisez les tris à plat pour les autres variables !

  • Âge
table(ENVIE2$age_rec,useNA="always")
  • Origine sociale
table(ENVIE2$par_men_5,useNA="always")
  • Avoir été en couple dans l’année précédant l’enquête
table(ENVIE2$couple12M,useNA="always")

Restriction de la population d’analyse

  • Figure uniquement sur les femmes et les hommes → il faut retirer les individus non-binaires de la base (genre_id = 3)

  • filter(BDD,condition)

  • On garde uniquement les individus dont genre_id vaut 1 ou 2
ENVIE3 <- filter(ENVIE2, 
                 genre_id == 1 | genre_id == 2)
  • OU on exclut les individus dont genre_id vaut 3
ENVIE3 <- filter(ENVIE2, 
                 genre_id != 3)

Identifier les données manquantes

Y a-t-il des données manquantes ?

table(ENVIE3$par_men_5,useNA="always")

   1    2    3    4    5 <NA> 
2142 2510 1925 1037 2093  196 
table(ENVIE3$couple12M,useNA="always")

   1    2    3 <NA> 
4283 2595 3001   24 

Traiter les données manquantes

  • Origine sociale: 196 NA sur 9 903 individus (≈ 2,0 % de l’échantillon)

  • Couple: 24 NA sur 9 903 individus (≈ 0,2 % de l’échantillon).

Relativement peu de non-réponses, on choisit de les exclure.

Supprimer les données manquantes

filter(BDD,complete.cases(var1, var2, ..., varN))

ENVIE3 <- filter(ENVIE3,complete.cases(couple12M, par_men_5))

Un objet peut en écraser un autre !

Assigner un résultat à un objet déjà existant écrase son contenu précédent, sans possibilité de retour en arrière immédiat.

Pour revenir à l’objet d’origine, il faut relancer la commande ayant permis de le créer.

Recoder les variables

Recoder les variables

Les variables de la figure ont-elles la même forme que dans le dictionnaire des codes ?

  • Découper l’âge en classes
  • Regrouper ou renommer certaines modalités
  • Créer des variables plus lisibles

Recoder l’âge en classe

  • Interface interactive icut()du package questionr
icut()

Sélection de la variable et des paramètres

Définition des classes d’âge

Vérification du résultat

Exécuter le code

⚠️ icut() génére le code mais ne l’exécute pas !

# Recodage de ENVIE3$age_rec en ENVIE3$age_tranche
ENVIE3$age_tranche <- cut(ENVIE3$age_rec, 
                          breaks = c(18, 21, 25, 29), 
                          include.lowest = TRUE, 
                          right = TRUE)

Ajouter des étiquettes

Argument labels=c("etiquette1","etiquette2")

# Recodage de ENVIE3$age_rec en ENVIE3$age_tranche
ENVIE3$age_tranche <- cut(ENVIE3$age_rec,
  include.lowest = TRUE,
  right = TRUE,
  dig.lab = 4,
  breaks = c(18, 21, 25, 29),
  labels = c("18-21 ans","22-25 ans","26-29 ans")
  ) 

Recoder l’origine sociale

  • Interface interactive irec()du package questionr
irec()

Sélection de la variable et des paramètres

Aparté: quelques définitions

Recodage ou labellisation ?

  • Labellisation des modalités = associer des intitulés compréhensibles à des codes
    • exemple: transformer 1, 2, 3 en "Homme", "Femme", "Autre"
  • Recodage analytique = regrouper des modalités pour construire une nouvelle variable
    • exemple: regrouper plusieurs PCS dans une catégorie "Classes populaires"

Par abus de langage, labellisation associée au recodage

Character ou factor ?

Dans R, une variable qualitative peut être stockée:

  • sous forme de character: chaque modalité est stockée comme du texte

  • sous forme de factor: modalités définies comme des catégories structurées (niveaux) Plusieurs avantages :

    • associer des labels à des codes
    • facilite la gestion de l’ordre des modalités
    • plus adapté à certaines analyses, plus économe en mémoire.

    Mais plus compliqué à manipuler !

Dans cet exercice, le « recodage » sert en fait à labelliser, transformer en factor pourrait suffire.
Mais plus compliqué à manipuler !
Pour débuter on recode/labellise en character.

Recodage (qui est en fait une labellisation)

Vérification du résultat

Exécuter le code

⚠️ irec() génére le code mais ne l’exécute pas !

# Recodage de ENVIE3$par_men_5 en ENVIE3$origine
ENVIE3$origine <- as.character(ENVIE3$par_men_5)
ENVIE3$origine[ENVIE3$par_men_5 == "1"] <- "cadre"
ENVIE3$origine[ENVIE3$par_men_5 == "2"] <- "intermédiaire"
ENVIE3$origine[ENVIE3$par_men_5 == "3"] <- "employée"
ENVIE3$origine[ENVIE3$par_men_5 == "4"] <- "petit indépendant"
ENVIE3$origine[ENVIE3$par_men_5 == "5"] <- "populaire"

Recoder (labelliser) l’origine sociale

À vous !

irec()
# Recodage de ENVIE3$genre_id en ENVIE3$genre_id_rec
ENVIE3$genre_id_rec <- as.character(ENVIE3$genre_id)
ENVIE3$genre_id_rec[ENVIE3$genre_id == "1"] <- "Homme"
ENVIE3$genre_id_rec[ENVIE3$genre_id == "2"] <- "Femme"

⚠️ Exécuter le code !

Recoder (cette fois vraiment !) le fait d’avoir été en couple dans l’année

À vous !

irec()
# Recodage de ENVIE3$couple12M en ENVIE3$couple12M_rec
ENVIE3$couple12M_rec <- as.character(ENVIE3$couple12M)
ENVIE3$couple12M_rec[ENVIE3$couple12M == "1"] <- "couple"
ENVIE3$couple12M_rec[ENVIE3$couple12M == "2"] <- "couple"
ENVIE3$couple12M_rec[ENVIE3$couple12M == "3"] <- "pas_couple"

⚠️ Exécuter le code !

Recodage alternatif avec dplyr

  • Utiliser les fonctions mutate() et case_when() du package dplyr.
  • Définition d’une série de conditions
  • Attribution d’une valeur à chaque condition
  • case_when(condition1 ~ valeur1, ...)
ENVIE3 <- ENVIE3 |>
  mutate(
    couple12M_rec_bis = case_when(
      couple12M == 1 | couple12M == 2 ~ "couple",
      couple12M == 3 ~ "pas_couple",
      TRUE ~ NA_character_
    ))

Calculer les tableaux croisés pondérés

Séparer les données selon le genre

  • Résultats présentés séparément pour les femmes et les hommes  → Créer deux sous-bases

Quelle fonction peut-on utiliser pour créer ces deux bases ?


HOMME<-filter(ENVIE3, genre_id_rec == "Homme")
FEMME<-filter(ENVIE3, genre_id_rec == "Femme")

Calculer les proportions pondérées

  • Pondération nécessaire pour avoir des résultats représentatifs de la population
  • wtd.table() du package questionr

Tri à plat pondéré

wtd.table(FEMME$couple12M_rec,
          weights=FEMME$poidscal)
    couple pas_couple 
   3192178    1205379 

Tri croisé pondéré

wtd.table(VariableEnLigne,VariableEnColonne,weights=pondération)

wtd.table(FEMME$age_tranche,
          FEMME$couple12M_rec,
          weights=FEMME$poidscal)
             couple pas_couple
18-21 ans  928270.8   572679.4
22-25 ans 1084949.2   376587.0
26-29 ans 1178958.3   256112.6

Pourcentages en ligne

lprop() du package questionr

wtd.table(FEMME$age_tranche,
          FEMME$couple12M_rec,
          weights=FEMME$poidscal) |> 
  lprop()
          couple pas_couple Total
18-21 ans  61.8   38.2      100.0
22-25 ans  74.2   25.8      100.0
26-29 ans  82.2   17.8      100.0
All        72.6   27.4      100.0

Enregistrer le tableau dans un objet

tab_f_age<- wtd.table(FEMME$age_tranche,
                      FEMME$couple12M_rec,
                      weights=FEMME$poidscal) |> 
  lprop()

Afficher le contenu du tableau

tab_f_age

Vérifier la classe de l’objet

class(tab_f_age)

À vous de créer les autres tableaux croisés nécessaires à la reproduction de la figure !

  • Proportion de femmes en couple selon l’origine sociale
tab_f_origine<-wtd.table(FEMME$origine,FEMME$couple12M_rec,weights=FEMME$poidscal) |> 
  lprop()
  • Proportion d’hommes en couple selon l’âge
tab_h_age<-wtd.table(HOMME$age_tranche,HOMME$couple12M_rec,weights=HOMME$poidscal) |> 
  lprop()

À vous de créer les autres tableaux croisés nécessaires à la reproduction de la figure !

  • Proportion d’hommes en couple selon l’origine sociale
tab_h_origine<-wtd.table(HOMME$origine,HOMME$couple12M_rec,weights=HOMME$poidscal) |> 
  lprop()

Mettre les résultats en forme pour la représentation graphique

Forme attendue

  • objet de type data.frame
  • base de données au format « long »

Étapes à suivre

  1. Transformer chaque tableau en objet data.frame
  2. Les assembler

Passer les tableaux au format data.frame

as.data.frame(tableau)

  • Proportion de femmes en couple selon l’âge
bdd_f_age<-as.data.frame(tab_f_age)
  • Vérification
class(bdd_f_age)
[1] "data.frame"

→ Mêmes informations, mais forme différente

Rendre le tableau explicite

  • Renommer les variables
bdd_f_age <- bdd_f_age |>  
  rename(modalite = Var1, couple = Var2)
  • Supprimer les marges et ne conserver que les proportions utiles
bdd_f_age <- filter(bdd_f_age, 
                    modalite!="Ensemble" 
                    & couple=="couple")

À vous maintenant de transformer les autres tableaux contenant les données à représenter !

  • Proportion de femmes en couple selon l’origine sociale
bdd_f_origine<-as.data.frame(tab_f_origine)

bdd_f_origine <- bdd_f_origine |>  
  rename(modalite = Var1, couple = Var2)

bdd_f_origine <- filter(bdd_f_origine, 
                        modalite!="Ensemble" 
                        & couple!="Total")
  • Avec le pipe |>
bdd_f_origine<-as.data.frame(tab_f_origine)|> 
  rename(modalite = Var1, couple = Var2) |> 
  filter(modalite!="Ensemble" 
         & couple=="couple")

À vous maintenant de transformer les autres tableaux contenant les données à représenter !

  • Proportion d’hommes en couple selon l’âge
bdd_h_age<-as.data.frame(tab_h_age)|> 
  rename(modalite = Var1, couple = Var2)|> 
  filter(modalite!="Ensemble" 
         & couple=="couple")

À vous maintenant de transformer les autres tableaux contenant les données à représenter !

  • Proportion d’hommes en couple selon l’origine sociale
bdd_h_origine<-as.data.frame(tab_h_origine)|> 
  rename(modalite = Var1, couple = Var2)|> 
  filter(modalite!="Ensemble" 
         & couple=="couple")

Réunir les tableaux dans une base unique

  • Graphique divisé en deux blocs :
    • la proportion de personnes ayant été en couple selon l’âge ;
    • la proportion de personnes ayant été en couple selon l’origine sociale.
  • Deux objets à créer:
    • un regroupant les données par âge (bdd_f_age et bdd_h_age) ;
    • un regroupant les données par origine sociale (bdd_f_origine et bdd_h_origine).

Base pour l’âge

  • Pour identifier les proportions correspondant aux femmes et aux hommes après la fusion, ajout d’une variable genre.
bdd_f_age$genre<-"Femme"
bdd_h_age$genre<-"Homme"
  • Empilement des deux bases : bind_rows(bdd1,bdd2)
bdd_age <- bind_rows(bdd_f_age, bdd_h_age)
  • Affichage du résultat
bdd_age
   modalite couple     Freq genre
1 18-21 ans couple 61.84554 Femme
2 22-25 ans couple 74.23348 Femme
3 26-29 ans couple 82.15331 Femme
4       All couple 72.58981 Femme
5 18-21 ans couple 55.88182 Homme
6 22-25 ans couple 56.62356 Homme
7 26-29 ans couple 69.75433 Homme
8       All couple 60.50462 Homme

Base pour l’origine sociale

À vous de jouer !

  • Ajout de la variable genre
bdd_f_origine$genre<-"Femme"
bdd_h_origine$genre<-"Homme"
  • Empilement des deux bases
bdd_origine <- bind_rows(bdd_f_origine, bdd_h_origine)

Réunion des deux bases

  • Même procédure que précédemment
  • Ajout d’une variable bloc
bdd_age$bloc<-"Âge"
bdd_origine$bloc<-"Origine sociale"
  • Réunion des deux bases
bdd_graphique <- bind_rows(bdd_age, bdd_origine)

Construction du graphique

Graphique à reproduire

  • Diagramme en barres

Choisir la bonne représentation graphique

Choisir la bonne représentation graphique

Le choix du graphique dépend de plusieurs éléments :

  • le type de variables utilisées (quantitatives ou qualitatives) ;
  • le nombre de variables à représenter ;
  • et surtout de l’objectif de l’analyse (comparer, décrire une distribution, montrer une relation, analyser une évolution temporelle, etc.).

Arbre de décision interactif pour vous aider dans le choix du graphique.

Construction interactive

Interface esquisser() du package Esquisse

  • Construction interactive
  • Génération du code correspondant (ggplot2)
esquisser()

Sélection des données

Construction du graphique

  • Glisser et déposer les variables dans les zones dédiées

  • X : modalite
    → catégories à comparer : classes d’âge ou catégories d’origine sociale

  • Y : Freq
    → pourcentages de personnes ayant été en couple dans l’année

  • fill : genre
    → distinguer les femmes et les hommes par des couleurs différentes

  • facet : bloc
    → séparer le graphique en deux parties : âge et origine sociale

Personnalisation du graphique

Mettre les barres côtes-à-côtes

  • Geometries
    • Position
      • dodge

Choisir les couleurs

  • Geometries
    • Use specific color
      • Femme : #E88A00
      • Homme : #077F11

Trouver les bonnes couleurs pour son graphique:

  • Identifier des couleurs

htmlcolorcodes

  • Utiliser des couleurs accessibles

package colorblindr

package khroma

colorbrewer

Pivoter le graphique

  • Axes
    • Coordinate system
      • flip

Fixer les bornes des pourcentages

Dans l’onglet Axes, repérer les options de l’axe correspondant à la variable Freq, puis indiquer :

  • Axes
    • Axe correspondant à la variable Freq
      • minimum : 0
      • maximum : 90

Organiser les deux parties du graphique

  • Facettes = blocs du graphique
  • Options
    • Facets
      • facet ncol : 1
      • facet scales : free_y
  • free_y : chaque facette affiche ses propres modalités
  • free : modifie aussi l’échelle des pourcentages

Ajouter le titre, les axes, la légende et la source

  • Labels & Title

    • Title : Avoir été en couple dans l’année selon l’âge et l’origine sociale

    • X label : Variable

    • Y label : %

    • Fill label : Genre

    • Caption : M. Bergström, F. Maillochon, l’équipe Envie, Population & Sociétés, n° 623, mai 2024, Ined. Source : Enquête Envie, Ined, 2023. Données pondérées.

Choisir un thème

  • Thème = apparence générale du graphique

  • Theme

    • minimal

Récupérer le code du graphique

  • Code
    • Insert code in script

Exécuter le code

library(ggplot2)

ggplot(bdd_graphique) +
  aes(x = modalite, y = Freq, fill = genre) +
  geom_col(position = "dodge") +
  scale_fill_manual(values = c(
    Femme = "#E88A00",
    Homme = "#077F11"
  )) +
  labs(
    x = "Variable",
    y = "%",
    title = "Avoir été en couple dans l'année selon l'âge et l'origine sociale",
    caption = "M. Bergström, F. Maillochon, l’équipe Envie, Population & Sociétés, n° 623, mai 2024, Ined. Source : Enquête Envie, Ined, 2023. Données pondérées.",
    fill = "Genre"
  ) +
  coord_flip() +
  theme_minimal() +
  theme(
    legend.justification = "right",
    plot.title = element_text(size = 12, face = "bold", hjust = 0.5),
    plot.caption = element_text(face = "italic", hjust = 0, size=6L),
    axis.title.y = element_text(size = 12, hjust = 1),
    legend.title = element_text(size = 12)
  ) +
  facet_wrap(vars(bloc), scales = "free_y", ncol = 1) +
  ylim(0, 90)