28  Définir un plan d’échantillonnage

Lorsque l’on travaille avec des données d’enquêtes, il est fréquent que les données soient pondérées. Cette pondération est nécessaire pour assurer la représentativité des données lorsque les participants ont été sélectionnés avec des probabilités variables. C’est par exemple le cas lorsqu’on réalise une enquête en grappes et/ou stratifiée.

De nombreuses fonctions acceptent une variable de pondération. Cependant, la simple prise en compte de la pondération est souvent insuffisante si l’on ne tient pas compte du plan d’échantillonnage de l’enquête. Le plan d’échantillonnage ne joue pas seulement sur la pondération des données, mais influence le calcul des variances et par ricochet tous les tests statistiques. Deux échantillons identiques avec la même variable de pondération mais des designs différents produiront les mêmes moyennes et proportions mais des intervalles de confiance différents.

Diverses fonctions de R peuvent prendre en compte une variable de pondération. Mais, en règle générale, elles sont incapables de tenir compte du plan d’échantillonnage. Il est donc préférable de privilégier le package survey qui est spécialement dédié au traitement d’enquêtes ayant des techniques d’échantillonnage et de pondération potentiellement très complexes. survey peut également être utilisée pour des pondérations simples.

28.1 Différents types d’échantillonnage

L’échantillonnage aléatoire simple ou échantillonnage équiprobable est une méthode pour laquelle tous les échantillons possibles (de même taille) ont la même probabilité d’être choisis et tous les éléments de la population ont une chance égale de faire partie de l’échantillon. C’est l’échantillonnage le plus simple : chaque individu à la même probabilité d’être sélectionné.

L’échantillonnage stratifié est une méthode qui consiste d’abord à subdiviser la population en groupes homogènes (strates) pour ensuite extraire un échantillon aléatoire de chaque strate. Cette méthode suppose une connaissance de la structure de la population. Pour estimer les paramètres, les résultats doivent être pondérés par l’importance relative de chaque strate dans la population.

L’échantillonnage par grappes est une méthode qui consiste à choisir un échantillon aléatoire d’unités qui sont elles-mêmes des sous-ensembles de la population (grappes ou clusters en anglais). Cette méthode suppose que les unités de chaque grappe sont représentatives. Elle possède l’avantage d’être souvent plus économique.

Il est possible de combiner plusieurs de ces approches. Par exemple, les Enquêtes Démographiques et de Santé1 (EDS) sont des enquêtes stratifiées en grappes à deux degrés. Dans un premier temps, la population est divisée en strates par région et milieu de résidence. Dans chaque strate, des zones d’enquêtes, correspondant à des unités de recensement, sont tirées au sort avec une probabilité proportionnelle au nombre de ménages de chaque zone au dernier recensement de population. Enfin, au sein de chaque zone d’enquête sélectionnée, un recensement de l’ensemble des ménages est effectué puis un nombre identique de ménages par zone d’enquête est tiré au sort de manière aléatoire simple.

  • 1 Vaste programme d’enquêtes réalisées à intervalles réguliers dans les pays à faible et moyen revenu, disponibles sur https://dhsprogram.com/.

  • 28.2 Avec survey::svydesign()

    La fonction survey::svydesign() accepte plusieurs arguments décrits en détail sur sa page d’aide (obtenue avec la commande ?svydesign).

    L'argument data permet de spécifier le tableau de données contenant les observations.

    L’argument ids est obligatoire et spécifie sous la forme d’une formule les identifiants des différents niveaux d’un tirage en grappe. S’il s’agit d’un échantillon aléatoire simple, on entrera ids = ~ 1. Autre situation : supposons une étude portant sur la population française. Dans un premier temps, on a tiré au sort un certain nombre de départements français. Dans un second temps, on tire au sort dans chaque département des communes. Dans chaque commune sélectionnée, on tire au sort des quartiers. Enfin, on interroge de manière exhaustive toutes les personnes habitant les quartiers enquêtés. Notre fichier de données devra donc comporter pour chaque observation les variables id_departement, id_commune et id_quartier. On écrira alors pour l’argument ids la valeur suivante :
    ids = ~ id_departement + id_commune + id_quartier.

    Si l’échantillon est stratifié, on spécifiera les strates à l’aide de l’argument strata en spécifiant la variable contenant l’identifiant des strates. Par exemple : strata = ~ id_strate.

    Il faut encore spécifier les probabilités de tirage de chaque cluster /grappe ou bien la pondération des individus. Si l’on dispose de la probabilité de chaque observation d’être sélectionnée, on utilisera l’argument probs. Si, par contre, on connaît la pondération de chaque observation (qui doit être proportionnelle à l’inverse de cette probabilité), on utilisera l’argument weights.

    Si l’échantillon est stratifié, qu’au sein de chaque strate les individus ont été tirés au sort de manière aléatoire et que l’on connaît la taille de chaque strate, il est possible de ne pas avoir à spécifier la probabilité de tirage ou la pondération de chaque observation. Il est préférable de fournir une variable contenant la taille de chaque strate à l’argument fpc. De plus, dans ce cas-là, une petite correction sera appliquée au modèle pour prendre en compte la taille finie de chaque strate.

    On peut tout à fait définir un échantillonnage aléatoire simple (on considère donc que toutes les observations ont le même poids, égal à 1). Pour rappel, en l’absence de clusters/grappes, il faut préciser ids = ~ 1, ce paramètre n’ayant pas de valeur par défaut.

    p_iris <- survey::svydesign(
      ids = ~ 1, 
      data = iris
    )
    Warning in svydesign.default(ids = ~1, data = iris): No weights or
    probabilities supplied, assuming equal probability
    p_iris
    Independent Sampling design (with replacement)
    survey::svydesign(ids = ~1, data = iris)

    Pour un jeu de données simplement pondéré (chaque ligne représente plusieurs observations) :

    titanic <- dplyr::as_tibble(Titanic)
    titanic |> labelled::look_for()
     pos variable label col_type missing values
     1   Class    —     chr      0             
     2   Sex      —     chr      0             
     3   Age      —     chr      0             
     4   Survived —     chr      0             
     5   n        —     dbl      0             
    p_titanic <- survey::svydesign(
      ids = ~ 1, 
      data = titanic, 
      weights = ~ n
    )
    p_titanic
    Independent Sampling design (with replacement)
    survey::svydesign(ids = ~1, data = titanic, weights = ~n)

    Pour un échantillon stratifié pour lequel les strates sont indiquées dans la variable stype et les poids indiquées dans la variable pw.

    data("api", package = "survey")
    p_strates <- survey::svydesign(
      id = ~ 1, 
      strata = ~ stype, 
      weights = ~ pw, 
      data = apistrat
    )
    p_strates
    Stratified Independent Sampling design (with replacement)
    survey::svydesign(id = ~1, strata = ~stype, weights = ~pw, data = apistrat)

    Pour une enquête en grappes à 1 degré, pour laquelle l’identifiant des grappes (clusters) est indiqué par la variable dnum.

    data("api", package = "survey")
    p_grappes <- survey::svydesign(
      id = ~ dnum, 
      weights = ~ pw, 
      data = apiclus1
    )
    p_grappes
    1 - level Cluster Sampling design (with replacement)
    With (15) clusters.
    survey::svydesign(id = ~dnum, weights = ~pw, data = apiclus1)

    Voici un exemple un peu plus complexe d’une enquête en grappes à deux degrés (les deux niveaux étant donnés par les variables dnum et snum). Les poids ne sont pas fournis mais la taille des grappes est connue et renseignée dans les variables fpc1 et fpc2 que nous pourrons donc transmettre via l’argument fpc.

    data("api", package = "survey")
    p_grappes2 <- survey::svydesign(
      id = ~ dnum + snum,
      fpc = ~ fpc1 + fpc2,
      data = apiclus2
    )
    p_grappes2
    2 - level Cluster Sampling design
    With (40, 126) clusters.
    survey::svydesign(id = ~dnum + snum, fpc = ~fpc1 + fpc2, data = apiclus2)

    Dans le cas présent, survey a calculé les poids s’appliquant à chaque individu. On peut les obtenir avec la fonction weights(), en l’occurrence avec p_grappes2 |> weights().

    Enfin, prenons l’exemple d’une Enquête Démographique et de Santé. Le nom des différentes variables est standardisé et commun quelle que soit l’enquête. Nous supposerons que vous avez importé le fichier individus dans un tableau de données nommés eds. Le poids statistique de chaque individu est fourni par la variable V005 qui doit au préalable être divisée par un million. Les grappes d’échantillonnage au premier degré sont fournies par la variable V021 (primary sample unit). Si elle n’est pas renseignée, on pourra utiliser le numéro de grappe V001. Enfin, le milieu de résidence (urbain / rural) est fourni par V025 et la région par V024. Pour rappel, l’échantillon a été stratifié à la fois par région et par milieu de résidence. Certaines enquêtes fournissent directement un numéro de strate via V022. Si tel est le cas, on pourra préciser le plan d’échantillonnage ainsi :

    eds$poids <- eds$V005/1000000
    p_eds <- survey::svydesign(
      ids = ~ V021, 
      data = eds, 
      strata = ~ V022, 
      weights = ~ poids
    )

    28.3 Avec srvyr::as_survey_design()

    Dans le prochain chapitre (cf. Chapitre 29), nous aborderons le package srvyr qui est aux objets survey ce que dplyr est aux tableaux de données : plus précisément, ce package étend les verbes de dplyr aux plans d’échantillonnage complexe.

    La fonction srvyr::as_survey_design() est équivalente à survey::svydesign() mais avec quelques différences :

    • le paramètre ids dispose d’une valeur par défaut et on peut l’ignorer en l’absence de grappes ;
    • les variables ne sont pas spécifiées avec une formule mais avec les mêmes sélecteurs que dplyr::select() ;
    • l’objet renvoyé est à la fois du type "survey.design" et du type "tbl_svy", une sorte de tibble pour les objets survey.

    Reprenons nos exemples précédents en commençant par un échantillonnage aléatoire simple.

    t_iris <- iris |> 
      srvyr::as_survey_design()
    t_iris
    Independent Sampling design (with replacement)
    Called via srvyr
    Sampling variables:
     - ids: `1`
    Data variables: Sepal.Length (dbl), Sepal.Width (dbl), Petal.Length (dbl),
      Petal.Width (dbl), Species (fct)
    class(t_iris)
    [1] "tbl_svy"        "survey.design2" "survey.design" 

    Pour un jeu de données simplement pondéré (chaque ligne représente plusieurs observations) :

    titanic <- dplyr::as_tibble(Titanic)
    t_titanic <- titanic |> 
      srvyr::as_survey_design(weights = n)
    t_titanic
    Independent Sampling design (with replacement)
    Called via srvyr
    Sampling variables:
     - ids: `1`
     - weights: n
    Data variables: Class (chr), Sex (chr), Age (chr), Survived (chr), n (dbl)

    Pour un échantillon stratifié pour lequel les strates sont indiquées dans la variable stype et les poids indiquées dans la variable pw.

    data("api", package = "survey")
    t_strates <- apistrat |> 
      srvyr::as_survey_design(strata = stype, weights = pw)
    t_strates
    Stratified Independent Sampling design (with replacement)
    Called via srvyr
    Sampling variables:
     - ids: `1`
     - strata: stype
     - weights: pw
    Data variables: cds (chr), stype (fct), name (chr), sname (chr), snum (dbl),
      dname (chr), dnum (int), cname (chr), cnum (int), flag (int), pcttest (int),
      api00 (int), api99 (int), target (int), growth (int), sch.wide (fct),
      comp.imp (fct), both (fct), awards (fct), meals (int), ell (int), yr.rnd
      (fct), mobility (int), acs.k3 (int), acs.46 (int), acs.core (int), pct.resp
      (int), not.hsg (int), hsg (int), some.col (int), col.grad (int), grad.sch
      (int), avg.ed (dbl), full (int), emer (int), enroll (int), api.stu (int), pw
      (dbl), fpc (dbl)

    Pour une enquête en grappes à 1 degré, pour laquelle l’identifiant des grappes (clusters) est indiqué par la variable dnum.

    data("api", package = "survey")
    t_grappes <- apiclus1 |> 
        srvyr::as_survey_design(id = dnum, weights = pw)
    t_grappes
    1 - level Cluster Sampling design (with replacement)
    With (15) clusters.
    Called via srvyr
    Sampling variables:
     - ids: dnum
     - weights: pw
    Data variables: cds (chr), stype (fct), name (chr), sname (chr), snum (dbl),
      dname (chr), dnum (int), cname (chr), cnum (int), flag (int), pcttest (int),
      api00 (int), api99 (int), target (int), growth (int), sch.wide (fct),
      comp.imp (fct), both (fct), awards (fct), meals (int), ell (int), yr.rnd
      (fct), mobility (int), acs.k3 (int), acs.46 (int), acs.core (int), pct.resp
      (int), not.hsg (int), hsg (int), some.col (int), col.grad (int), grad.sch
      (int), avg.ed (dbl), full (int), emer (int), enroll (int), api.stu (int), fpc
      (dbl), pw (dbl)

    Voici un exemple un peu plus complexe d’une enquête en grappes à deux degrés (les deux niveaux étant donnés par les variables dnum et snum). Les poids ne sont pas fournis mais la taille des grappes est connue et renseignée dans les variables fpc1 et fpc2 que nous pourrons donc transmettre via l’argument fpc.

    data("api", package = "survey")
    data("api", package = "survey")
    t_grappes2 <- apiclus2 |> 
        srvyr::as_survey_design(id = c(dnum, snum), fpc = c(fpc1, fpc2))
    t_grappes2
    2 - level Cluster Sampling design
    With (40, 126) clusters.
    Called via srvyr
    Sampling variables:
     - ids: `dnum + snum`
     - fpc: `fpc1 + fpc2`
    Data variables: cds (chr), stype (fct), name (chr), sname (chr), snum (dbl),
      dname (chr), dnum (int), cname (chr), cnum (int), flag (int), pcttest (int),
      api00 (int), api99 (int), target (int), growth (int), sch.wide (fct),
      comp.imp (fct), both (fct), awards (fct), meals (int), ell (int), yr.rnd
      (fct), mobility (int), acs.k3 (int), acs.46 (int), acs.core (int), pct.resp
      (int), not.hsg (int), hsg (int), some.col (int), col.grad (int), grad.sch
      (int), avg.ed (dbl), full (int), emer (int), enroll (int), api.stu (int), pw
      (dbl), fpc1 (dbl), fpc2 (int[1d])

    Enfin, prenons l’exemple d’une Enquête Démographique et de Santé. Le nom des différentes variables est standardisé et commun quelle que soit l’enquête. Nous supposerons que vous avez importé le fichier individus dans un tableau de données nommés eds. Le poids statistique de chaque individu est fourni par la variable V005 qui doit au préalable être divisée par un million. Les grappes d’échantillonnage au premier degré sont fournies par la variable V021 (primary sample unit). Si elle n’est pas renseignée, on pourra utiliser le numéro de grappe V001. Enfin, le milieu de résidence (urbain / rural) est fourni par V025 et la région par V024. Pour rappel, l’échantillon a été stratifié à la fois par région et par milieu de résidence. Certaines enquêtes fournissent directement un numéro de strate via V022. Si tel est le cas, on pourra préciser le plan d’échantillonnage ainsi :

    eds$poids <- eds$V005/1000000
    t_eds <- eds |> 
      srvyr::as_survey_design(
        ids = V021,
        strata = V022,
        weights = poids
      )

    28.4 webin-R

    La statistique univariée est présentée dans le webin-R #10 (données pondérées, plan d’échantillonnage complexe & survey) sur YouTube.