cassionAnalyse de données

Retour à la leçonLeçon 3 sur 8Des données qui gardent leur sens

Les fichiers Stata et SPSS gardent leurs étiquettes

Le même diaporama que les téléchargements, rendu sous forme de page. Lancez le diaporama pour le présenter en plein écran — les flèches ou un clic avancent d'une diapositive, Échap quitte.

Diapositives · PDFDiapositives · PowerPoint

  1. Diapositive 1 / 23

    Ce que couvre cette leçon

    • Ce qu'un CSV jette
    • La classe labelled
    • Convertir délibérément
    • Les deux façons de perdre un dictionnaire de codes
    • Les valeurs manquantes définies par l'utilisateur
    • SPSS et les autres formats
    • Où cela rejoint le cours Python
    • Ce qui vient ensuite
    Notes du présentateur
    haven, la classe labelled, et pourquoi le .dta d'un institut de sondage doit être lu sous R même si l'analyse se fait ailleurs — plus les deux façons de perdre un dictionnaire de codes sans s'en apercevoir.
  2. Diapositive 2 / 23

    Ce qu'un CSV jette — En R

    library(haven)
    
    survey <- read_dta(here("data", "raw", "household-survey.dta"))
    Notes du présentateur
    Un institut de sondage livre un .dta ou un .sav. À l'intérieur, une colonne n'est pas seulement des valeurs — elle porte une étiquette de variable (« Le chef de ménage a consenti à l'entretien ») et des étiquettes de valeurs (1 = Oui, 2 = Non, 9 = Ne sait pas). Exportez-le en CSV et les deux disparaissent. Vous obtenez une colonne de 1, 2 et 9, un dictionnaire de codes en PDF que quelqu'un doit conserver, et une moyenne de 1,7 qui ne signifie rien. haven lit les étiquettes en même temps que les valeurs. C'est la raison d'être de cette leçon, et la raison de lire un fichier d'enquête sous R même si l'analyse se fera en Python : R préserve davantage du fichier que pandas, et un CSV accompagné d'un dictionnaire que vous avez écrit vous-même est un moins bon artefact que l'original.
  3. Diapositive 3 / 23

    La classe labelled — En R

    class(survey$consent)
    #> [1] "haven_labelled" "vctrs_vctr" "double"
    
    attr(survey$consent, "labels")
    #>        Oui        Non Ne sait pas
    #>          1          2           9
    
    attr(survey$consent, "label")
    #> [1] "Le chef de menage a consenti a l'entretien"
    Notes du présentateur
    read_dta() vous donne des colonnes de classe haven_labelled : les valeurs sous-jacentes, avec leurs étiquettes attachées.
  4. Diapositive 4 / 23

    La classe labelled — En R

    mean(survey$consent, na.rm = TRUE)
    #> [1] 1.7
    Notes du présentateur
    Les valeurs sont toujours là — l'arithmétique fonctionne — et c'est justement le piège. Une colonne étiquetée est un nombre du point de vue de mean() : Ce chiffre est la moyenne de 1, 2 et 9. Il n'a aucun sens et il n'avertit de rien.
  5. Diapositive 5 / 23

    Convertir délibérément

    • Une variable catégorielle devient un facteur
    Notes du présentateur
    haven propose trois gestes, et le bon dépend de ce qu'est la colonne. Une variable catégorielle devient un facteur.
  6. Diapositive 6 / 23

    Convertir délibérément — En R

    library(dplyr)
    
    survey <- survey |>
      mutate(consent = as_factor(consent))
    
    levels(survey$consent)
    #> [1] "Oui" "Non" "Ne sait pas"
  7. Diapositive 7 / 23

    Convertir délibérément

    • Un véritable nombre perd ses étiquettes
    Notes du présentateur
    as_factor() — celui de haven, non le as.factor() de base — utilise les étiquettes de valeurs comme niveaux, dans l'ordre que le fichier déclare plutôt qu'alphabétiquement. Cet ordre est un cadeau : celui du dictionnaire de codes est généralement celui qu'un rapport attend. Un véritable nombre perd ses étiquettes.
  8. Diapositive 8 / 23

    Convertir délibérément — En R

    survey <- survey |> mutate(hh_size = zap_labels(hh_size))
  9. Diapositive 9 / 23

    Convertir délibérément

    • Tout d'un coup, quand le fichier est uniformément catégoriel
    Notes du présentateur
    zap_labels() retire l'étiquetage et laisse les valeurs. À employer là où la colonne est réellement une quantité qui portait accessoirement une étiquette. Tout d'un coup, quand le fichier est uniformément catégoriel :
  10. Diapositive 10 / 23

    Convertir délibérément — En R

    survey <- read_dta(path) |> as_factor()
    Notes du présentateur
    Appliquer as_factor() au tibble entier convertit chaque colonne étiquetée. Rapide, et faux pour tout fichier mêlant catégories et quantités — vérifiez avec glimpse() avant d'y recourir.
  11. Diapositive 11 / 23

    Les deux façons de perdre un dictionnaire de codes

    • Lire avec les étiquettes déjà appliquées
  12. Diapositive 12 / 23

    Les deux façons de perdre un dictionnaire de codes — En R

    survey <- read_dta(path, .name_repair = "unique")
    survey <- as_factor(survey)          # les valeurs ont disparu, restent les etiquettes
  13. Diapositive 13 / 23

    Les deux façons de perdre un dictionnaire de codes — En R

    survey <- read_dta(path)
    
    codes <- survey |> mutate(across(where(is.labelled), zap_labels))
    labels <- survey |> as_factor()
    Notes du présentateur
    Les codes sous-jacents sont désormais indisponibles. Cela compte plus qu'il n'y paraît : le dictionnaire, le questionnaire, le plan de tabulation et toute analyse antérieure renvoient tous à 1 et 2. À un collègue qui demande « combien ont été codés 9 ? », un facteur ne répond pas. Gardez les deux :
  14. Diapositive 14 / 23

    Les deux façons de perdre un dictionnaire de codes

    • Écrire le CSV et passer à autre chose
  15. Diapositive 15 / 23

    Les deux façons de perdre un dictionnaire de codes — En R

    readr::write_csv(as_factor(survey), "survey.csv")
  16. Diapositive 16 / 23

    Les deux façons de perdre un dictionnaire de codes — En R

    codebook <- tibble::tibble(
      variable = names(survey),
      label    = vapply(survey, function(x) attr(x, "label") %||% NA_character_, character(1))
    )
    
    readr::write_csv(codebook, "survey-codebook.csv")
    Notes du présentateur
    Le CSV porte désormais "Oui" et "Non", ce qui est lisible et perd dans une autre direction : les codes ont disparu, et avec eux la distinction entre « Ne sait pas » et une véritable valeur manquante. Si vous devez remettre un CSV à une analyse Python, remettez un dictionnaire avec lui, généré depuis le fichier plutôt que saisi : Les étiquettes de valeurs demandent une ligne par niveau, ce que labelled::look_for() produit directement si vous disposez de ce paquet. Dans tous les cas, le dictionnaire est dérivé, non transcrit — un dictionnaire transcrit s'écarte du fichier qu'il décrit.
  17. Diapositive 17 / 23

    Les valeurs manquantes définies par l'utilisateur — En R

    survey$income
    #> <labelled<double>[3]>
    #> [1]  4500 NA(a) NA(b)
    Notes du présentateur
    Stata et SPSS distinguent des sortes de manquant : refus, sans objet, non posé. haven les préserve sous forme de NA étiquetés plutôt que de les fondre en un seul.
  18. Diapositive 18 / 23

    Les valeurs manquantes définies par l'utilisateur — En R

    survey <- survey |> mutate(income = zap_missing(income))
    Notes du présentateur
    NA(a) et NA(b) restent des NA pour is.na() : rien ne devient donc silencieusement un nombre. Mais la distinction survit, et elle est souvent le constat — une question refusée par 40 % des répondants est un problème différent d'une question qui ne les concernait pas. zap_missing() les aplatit en NA ordinaires une fois que vous les avez comptés. Comptez d'abord.
  19. Diapositive 19 / 23

    SPSS et les autres formats — En R

    read_sav(path)     # SPSS .sav
    read_por(path)     # SPSS portable
    read_dta(path)     # Stata
    read_xpt(path)     # SAS transport
  20. Diapositive 20 / 23

    SPSS et les autres formats — En R

    write_dta(survey, "cleaned.dta")
    Notes du présentateur
    Tous renvoient la même structure étiquetée : tout ce qui précède s'applique tel quel. L'écriture est symétrique, et parfois nécessaire quand un ministère attend un .dta : Stata impose aux noms de variables des règles que R n'a pas — pas de points, 32 caractères — et write_dta() lèvera une erreur plutôt que de les déformer silencieusement. C'est le comportement souhaitable.
  21. Diapositive 21 / 23

    Où cela rejoint le cours Python

    • Le cours Python pour les données de programme dit, dans sa leçon sur les codes et les sentinelles, que c'est le seul endroit où la réponse est « utilisez l'autre langage ».
    Notes du présentateur
    Le cours Python pour les données de programme dit, dans sa leçon sur les codes et les sentinelles, que c'est le seul endroit où la réponse est « utilisez l'autre langage ». C'est cette leçon-ci qu'il désigne. pandas lit un .dta et vous donne soit les codes, soit les étiquettes, jamais les deux, et ne préserve pas du tout les valeurs manquantes étiquetées. Si les étiquettes comptent — et sur un fichier d'enquête, c'est toujours le cas — lisez sous R, convertissez délibérément, et exportez à la fois les codes et un dictionnaire dérivé.
  22. Diapositive 22 / 23

    Ce qui vient ensuite

    • Les étiquettes sont attachées et converties en facteurs.
    Notes du présentateur
    Les étiquettes sont attachées et converties en facteurs. La leçon suivante porte sur ce qu'est réellement un facteur en R, et sur le problème d'ordre que as_factor() a résolu ici pour vous et ne résoudra pas pour une colonne que vous construisez vous-même.
  23. Diapositive 23 / 23

    La suite

    Lire la leçon complète, avec le code exécutable Retour à la leçon