-
Notifications
You must be signed in to change notification settings - Fork 42
/
donnees-ponderees.Rmd
282 lines (214 loc) · 12.8 KB
/
donnees-ponderees.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
---
title: "Données pondérées"
---
```{r options_communes, include=FALSE, cache=FALSE}
source("options_communes.R")
```
<div class="guide-R">
Une version actualisée de ce chapitre est disponible sur **guide-R** à travers plusieurs chapitres : [Définir un plan d’échantillonnage](https://larmarange.github.io/guide-R/donnees_ponderees/plan-echantillonnage.html), [Manipulation de données pondérées](https://larmarange.github.io/guide-R/donnees_ponderees/manipulation.html), [Analyses uni- et bivariées pondérées](https://larmarange.github.io/guide-R/donnees_ponderees/analyses-bivariees.html) et [Graphiques pondérés](https://larmarange.github.io/guide-R/donnees_ponderees/graphiques-ponderes.html).
</div>
<div class="webin-R">
Ce chapitre est évoqué dans le webin-R #10 (Données pondérées, plan d'échantillonnage complexe & survey) sur [YouTube](https://youtu.be/aXCn9SyhcTE).
</div>
S'il est tout à fait possible de travailler avec des <dfn>données pondérées</dfn> sous R, cette fonctionnalité n'est
pas aussi bien intégrée que dans la plupart des autres logiciels de traitement statistique. En particulier,
il y a plusieurs manières possibles de gérer la <dfn>pondération</dfn>. Cependant, lorsque l'on doit
également prendre un compte un <dfn>plan d'échantillonnage</dfn><dfn data-index="échantillonnage, plan"></dfn>
complexe (voir section dédiée ci-après), **R** fournit tous les outils nécessaires, alors que dans la
plupart des logiciels propriétaires, il faut disposer d'une extension adéquate, pas toujours vendue de base
avec le logiciel.
Dans ce qui suit, on utilisera le jeu de données tiré de l'enquête *Histoire de vie* et notamment sa
variable de pondération *poids*^[On notera que cette variable est utilisée à titre purement illustratif.
Le jeu de données étant un extrait d'enquête et la variable de pondération n'ayant pas été recalculée,
elle n'a ici à proprement parler aucun sens.].
```{r}
library(questionr)
data(hdv2003)
d <- hdv2003
range(d$poids)
```
## Options de certaines fonctions
Tout d'abord, certaines fonctions de **R** acceptent en argument un vecteur permettant de pondérer les
observations (l'option est en général nommée `weights` ou `row.w`). C'est le cas par exemple des méthodes
d'estimation de modèles linéaires^[Voir le chapitre [régression linéaire](regression-lineaire.html).]
(`lm`{data-pkg="stats"}) ou de modèles linéaires généralisés ^[Voir le chapitre sur la
[régression logistique](regression-logistique.html).]
(`glm`{data-pkg="stats"}) ou dans les analyses de correspondances^[Voir le chapitre dédié à
l'[analyse des correspondances](analyse-des-correspondances-multiples.html).]
des extensions `ade4`{.pkg} ou `FactoMineR`{.pkg}.
Par contre cette option n'est pas présente dans les fonctions de base comme `mean`{data-pkg="base"},
`var`{data-pkg="base" data-rdoc="cor"}, `table`{data-pkg="base"} ou
`chisq.test`{data-pkg="stats"}.
## Données pondérées avec l'extension survey{#survey}
L'extension `survey`{.pkg} est spécialement dédiée au traitement d'enquêtes
ayant des techniques d'échantillonnage et de pondération potentiellement très complexes.
L'extension s'installe comme la plupart des autres :
```{r, eval=FALSE}
install.packages("survey")
```
Le site officiel (en anglais) comporte beaucoup d'informations, mais pas forcément très accessibles :
<br /><http://r-survey.r-forge.r-project.org/>.
Pour utiliser les fonctionnalités de l'extension, on doit d'abord définir le <dfn>plan d'échantillonnage</dfn>
ou <dfn lang="en">design</dfn> de notre enquête, c'est-à-dire indiquer quel type de
pondération nous souhaitons lui appliquer.
Dans un premier temps, nous utiliserons le plan d'échantillonnage le plus simple,
avec une variable de pondération déjà calculée. Pour d'autres types de plan d'échantillonnage, voir
la chapitre sur les [plans d'échantillonnage complexes](definir-un-plan-d-echantillonnage-complexe.html).
Ceci se fait à l'aide de la fonction `svydesign`{data-pkg="survey"} :
```{r, message=FALSE}
library(survey)
dw <- svydesign(ids = ~1, data = d, weights = ~d$poids)
```
Cette fonction crée un nouvel objet, que nous avons nommé `dw`. Cet objet n'est pas à proprement
parler un tableau de données, mais plutôt un tableau de données plus une méthode de pondération. `dw`
et `d` sont des objets distincts, les opérations effectuées sur l'un n'ont pas d'influence sur l'autre.
On peut cependant retrouver le contenu de `d` depuis `dw` en utilisant `dw$variables` :
```{r}
str(d$age)
str(dw$variables$age)
```
Lorsque notre plan d'échantillonnage est déclaré,
on peut lui appliquer une série de fonctions permettant d'effectuer
diverses opérations statistiques en tenant compte de la pondération. On citera notamment :
* `svymean`{data-pkg="survey" data-rdoc="surveysummary"},
`svyvar`{data-pkg="survey" data-rdoc="surveysummary"},
`svytotal`{data-pkg="survey" data-rdoc="surveysummary"},
`svyquantile`{data-pkg="survey"} : <dfn data-index="statistique univariée">statistiques univariées</dfn>
<dfn data-index="univariée, statistique"></dfn>(<dfn>moyenne</dfn>, <dfn>variance</dfn>, <dfn>total</dfn>,
<dfn data-index="quantile">quantiles</dfn>)
* `svytable`{data-pkg="survey"} : <dfn>tri à plat</dfn> et <dfn>tableau croisé</dfn>
* `svychisq`{data-pkg="survey" data-rdoc="svytable"} : <dfn data-index="test du Chi²">test du χ²</dfn>
<dfn data-index="Chi², test"></dfn>
* `svyby`{data-pkg="survey"} : statistiques selon un facteur
* `svyttest`{data-pkg="survey"} : <dfn>test t de Student</dfn><dfn data-index="Student, test-t"></dfn>
de <dfn>comparaison de moyennes</dfn><dfn data-index="moyenne, comparaison"></dfn>
* `svyciprop`{data-pkg="survey"} : <dfn>intervalle de confiance d'une proportion</dfn><dfn data-index="proportion, intervalle de confiance"></dfn>
* `svyglm`{data-pkg="survey"} : <dfn data-index="modèle linéaire généralisé">modèles linéaires généralisés</dfn>
(dont <dfn>régression logistique</dfn><dfn data-index="logistique, régression"></dfn>)
* `svyplot`{data-pkg="survey"},
`svyhist`{data-pkg="survey"},
`svyboxplot`{data-pkg="survey" data-rdoc="svyhist"} : fonctions graphiques
D'autres fonctions sont disponibles, comme `svyratio`{data-pkg="survey"},
mais elles ne seront pas abordées ici.
Pour ne rien arranger, ces fonctions prennent leurs arguments sous forme de
formules^[Pour plus de détails sur les formules, voir le [chapitre dédié](formules.html).],
c'est-à-dire pas de la manière habituelle.
En général l'appel de fonction se fait en spécifiant d'abord les variables d'intérêt
sous forme de formule, puis l'objet *survey.design*.
Voyons tout de suite quelques exemples^[Pour d'autres exemples,
voir <http://www.ats.ucla.edu/stat/r/faq/svy_r_oscluster.htm> (en anglais).] :
```{r}
svymean(~age, dw)
svyquantile(~age, dw, quantile = c(0.25, 0.5, 0.75), ci = TRUE)
svyvar(~heures.tv, dw, na.rm = TRUE)
```
Les tris à plat se déclarent en passant comme argument le nom de la variable précédé
d'un tilde (`~`), tandis que les tableaux croisés utilisent les noms des deux variables
séparés par un signe plus (`+`) et précédés par un tilde (`~`).
```{r}
svytable(~sexe, dw)
svytable(~sexe + clso, dw)
```
La fonction `freq`{data-pkg="questionr"} peut être utilisée si on lui passe
en argument non pas la variable elle-même, mais son tri à plat obtenu avec
`svytable`{data-pkg="survey"} :
```{r}
tab <- svytable(~peche.chasse, dw)
freq(tab, total = TRUE)
```
On peut également récupérer le tableau issu de `svytable`{data-pkg="survey"} dans un objet et
le réutiliser ensuite comme n'importe quel tableau croisé :
```{r}
tab <- svytable(~sexe + clso, dw)
tab
```
Les fonctions `lprop`{data-pkg="questionr" data-rdoc="rprop"} et
`cprop`{data-pkg="questionr"} de `questionr`{.pkg} sont donc
tout à fait compatibles avec l'utilisation de `survey`{.pkg}.
```{r}
lprop(tab)
```
Le principe de la fonction `svyby`{data-pkg="survey"} est similaire à celui de
`tapply`{data-pkg="base"}^[La fonction `tapply`{data-pkg="base"} est présentée plus en
détails dans le chapitre [Manipulation de données](pem_manipulation.html#tapply).]. Elle
permet de calculer des statistiques selon plusieurs sous-groupes définis par un facteur.
Par exemple :
```{r}
svyby(~age, ~sexe, dw, svymean)
```
### gtsummary et survey
L'extension `gtsummary`{.pkg} fournit une fonction `tbl_svysummary`{data-pkg="gtsummary"}, similaire à `tbl_summary`{data-pkg="gtsummary"}, mais adaptée aux objets `survey`.
```{r}
library(gtsummary)
theme_gtsummary_language("fr", decimal.mark = ",", big.mark = " ")
dw %>% tbl_svysummary(include = c("age", "sexe", "clso", "peche.chasse"))
dw %>%
tbl_svysummary(
include = c("age", "sexe", "clso", "peche.chasse"),
by = "sexe"
) %>%
add_overall(last = TRUE) %>%
add_p()
```
### Graphiques natifs avec survey
`survey`{.pkg} est également capable de produire des graphiques à partir
des données pondérées. Quelques exemples :
<figure>
```{r}
par(mfrow = c(2, 2))
svyplot(~age + heures.tv, dw, col = "red", main = "Bubble plot")
svyhist(~heures.tv, dw, col = "peachpuff", main = "Histogramme")
svyboxplot(age ~ 1, dw, main = "Boxplot simple", ylab = "Âge")
svyboxplot(age ~ sexe, dw, main = "Boxplot double", ylab = "Âge", xlab = "Sexe")
```
<figcaption>Fonctions graphiques de l'extension survey</figcaption>
</figure>
### Graphiques ggplot2
`ggplot2`{.pkg} accepte une esthétique `weight` pour indiquer des poids à prendre en compte dans les différents graphiques. La fonction `weights`{data-pkg="survey" data-rdoc="weights.survei.design"} permets justement de récupérer les poids d'un objet `survey`. La fonction `ggplot`{data-pkg="ggplot2"} n'accepte pas d'objet `survey` mais a besoin d'un tableau de données. Ce dernier peut être récupéré avec `$variables`.
```{r}
library(ggplot2)
ggplot(dw$variables) +
aes(weight = weights(dw), x = sexe, fill = clso) +
geom_bar(position = "fill")
```
**ATTENTION :** les graphiques obtenus ne sont corrects qu'à la condition que seuls les poids soient nécessaires pour les construire, ce qui est le cas d'un nuage de points ou d'un diagramme en barres. Par contre, si le calcul du graphique implique le calcul de variance, la représentation sera incorrecte. Par exemple, avec `geom_smooth`{data-pkg="ggplot2"}, les aires de confiance affichées ne prendront pas correctement en compte le plan d'échantillonnage.
<div class="note">
L'extenstion `questionr` propose, dans sa version de développement, une fonction `ggsurvey`{data-pkg="questionr"} pour faciliter les choses. Elle prend un objet `survey`, extrait le tableau de données et les poids, associe les poids à l'esthétique correspondante et appelle `ggplot`{data-pkg="ggplot2"}.
```{r}
library(questionr)
ggsurvey(dw) +
aes(x = sexe, fill = clso) +
geom_bar(position = "fill")
```
Pour installer la version de développement de `questionr`{.pkg}, on pourra utiliser la commande suivante :
```{r eval=FALSE}
if (!require(devtools)){
install.packages('devtools')
library(devtools)
}
install_github("juba/questionr")
```
</div>
### Extraire un sous-échantillon
Si l'on souhaite travailler sur un <dfn>sous-échantillon</dfn> tout en gardant les informations d'échantillonnage,
on utilisera la fonction `subset`{data-pkg="survey" data-rdoc="subset.survey.design"}
présentée en détail dans le chapitre [Sous-ensembles](sous-ensembles.html).
```{r}
sous <- subset(dw, sexe == "Femme" & age >= 40)
```
### Modèles logistiques
Pour réaliser des modèles logistiques (binaires, multinomiaux ou ordinaux) avec prise en compte d'un plan d'échantillonnage, on pourra se référer à la [sous-section dédiée du chapitre Régression logistique](regression-logistique.html#survey).
### dplyr et survey
L'extension `srvyr`{.pkg} vise à permettre d'utiliser les verbes de `dplyr`{.pkg} avec `survey`{.pkg}. Le fonctionnement de cette extension est expliqué dans une vignette dédiée : <https://cran.r-project.org/web/packages/srvyr/vignettes/srvyr-vs-survey.html>.
## Conclusion
Si, la gestion de la pondération sous **R** n'est sans doute pas ce qui se fait de plus
pratique et de plus simple, on pourra quand même donner les conseils suivants :
* utiliser les options de pondération des fonctions usuelles ou les fonctions d'extensions
comme `questionr`{.pkg} pour les cas les plus simples ;
* si on utilise `survey`{.pkg}, effectuer autant que possible tous les
recodages et manipulations sur les données non pondérées ;
* une fois les recodages effectués, on déclare le design et on fait les analyses en tenant compte
de la pondération ;
* surtout ne jamais modifier les variables du design. Toujours effectuer recodages et manipulations
sur les données non pondérées, puis redéclarer le design pour que les mises à jour effectuées soient
disponibles pour l'analyse.