Sous-ensembles
Dans ce qui suit on travaillera sur le jeu de données tiré de l’enquête Histoire de vie, fourni avec l’extension questionr
.
library(questionr)
data(hdv2003)
<- hdv2003 d
Par indexation
La première manière de construire des sous-populations est d’utiliser l’indexation par conditions. On peut ainsi facilement sélectionner une partie des observations suivant un ou plusieurs critères et placer le résultat dans un nouveau tableau de données.
Par exemple si l’on souhaite isoler les hommes et les femmes :
<- d[d$sexe == "Homme", ]
dh <- d[d$sexe == "Femme", ]
df table(d$sexe)
Homme | Femme |
---|---|
899 | 1101 |
dim(dh)
[1] 899 20
dim(df)
[1] 1101 20
On a à partir de là trois tableaux de données, d
comportant la population totale, dh
seulement les hommes et df
seulement les femmes.
On peut évidemment combiner plusieurs critères :
.25 <- d[d$sexe == "Homme" & d$age <= 25, ]
dhdim(dh.25)
[1] 86 20
Si on utilise directement l’indexation, il convient cependant d’être extrêmement prudent avec les valeurs manquantes. Comme indiqué précédemment, la présence d’une valeur manquante dans une condition fait que celle-ci est évaluée en NA
et qu’au final la ligne correspondante est conservée par l’indexation :
summary(d$trav.satisf)
Satisfaction Insatisfaction Equilibre NA's
480 117 451 952
<- d[d$trav.satisf == "Satisfaction", ]
d.satisf dim(d.satisf)
[1] 1432 20
Comme on le voit, ici d.satisf
contient les individus ayant la modalité Satisfaction mais aussi ceux ayant une valeur manquante NA
. C’est pourquoi il faut toujours soit vérifier au préalable qu’on n’a pas de valeurs manquantes dans les variables de la condition, soit exclure explicitement les NA
de la manière suivante :
<- d[d$trav.satisf == "Satisfaction" & !is.na(d$trav.satisf), ]
d.satisf dim(d.satisf)
[1] 480 20
C’est notamment pour cette raison qu’on préfèrera le plus souvent utiliser la fonction subset
.
Fonction subset
La fonction subset
permet d’extraire des sous-populations de manière plus simple et un peu plus intuitive que l’indexation directe.
Celle-ci prend trois arguments principaux :
- le nom de l’objet de départ ;
- une condition sur les observations (
subset
) ; - éventuellement une condition sur les colonnes (
select
).
Reprenons tout de suite un exemple déjà vu :
<- subset(d, sexe == "Homme")
dh <- subset(d, sexe == "Femme") df
L’utilisation de subset
présente plusieurs avantages. Le premier est d’économiser quelques touches. On n’est en effet pas obligé de saisir le nom du tableau de données dans la condition sur les lignes. Ainsi les deux commandes suivantes sont équivalentes :
<- subset(d, d$sexe == "Homme")
dh <- subset(d, sexe == "Homme") dh
Le second avantage est que subset
s’occupe du problème des valeurs manquantes évoquées précédemment et les exclut de lui-même, contrairement au comportement par défaut :
summary(d$trav.satisf)
Satisfaction Insatisfaction Equilibre NA's
480 117 451 952
<- d[d$trav.satisf == "Satisfaction", ]
d.satisf dim(d.satisf)
[1] 1432 20
<- subset(d, trav.satisf == "Satisfaction")
d.satisf dim(d.satisf)
[1] 480 20
Dans le cas présent, l’extraction obtenue avec subset
est équivalente à :
<- d[d$trav.satisf == "Satisfaction" & !is.na(d$trav.satisf), ]
d.satisf dim(d.satisf)
[1] 480 20
Enfin, l’utilisation de l’argument select
est simplifié pour l’expression de condition sur les colonnes. On peut ainsi spécifier les noms de variable sans guillemets et leur appliquer directement l’opérateur d’exclusion -
:
<- subset(d, select = c(sexe, sport))
d2 <- subset(d, age > 25, select = -c(id, age, cinema)) d2
Fonction tapply
Cette section documente une fonction qui peut être très utile, mais pas forcément indispensable au départ.
La fonction tapply
n’est qu’indirectement liée à la notion de sous-population, mais peut permettre d’éviter d’avoir à créer ces sous-populations dans certains cas.
Son fonctionnement est assez simple, mais pas forcément intuitif. La fonction prend trois arguments : un vecteur, un facteur et une fonction. Elle applique ensuite la fonction aux éléments du vecteur correspondant à un même niveau du facteur. Vite, un exemple !
tapply(d$age, d$sexe, mean)
Homme Femme
48.16129 48.15350
Qu’est-ce que ça signifie ? Ici tapply
a sélectionné toutes les observations correspondant à « Homme », puis appliqué la fonction mean
aux valeurs de age correspondantes. Puis elle a fait de même pour les observations correspondant à « Femme ». On a donc ici la moyenne d’âge chez les hommes et chez les femmes.
On peut fournir à peu près n’importe quelle fonction à tapply
:
tapply(d$bricol, d$sexe, freq)
$Homme
Frequency table
Class: factor (numeric)
Length: 899
Levels: 2: Non, Oui
Available: 899 (100%, NA: 0 = 0%)
Unique: 2
Item Count Percent Cum. Count Cum. Percent
--- ------ ------- --------- ------------ --------------
1 Oui 515 57.29% 515 57.29%
2 Non 384 42.71% 899 100.00%
$Femme
Frequency table
Class: factor (numeric)
Length: 1,101
Levels: 2: Non, Oui
Available: 1,101 (100%, NA: 0 = 0%)
Unique: 2
Item Count Percent Cum. Count Cum. Percent
--- ------ ------- --------- ------------ --------------
1 Non 763 69.3% 763 69.3%
2 Oui 338 30.7% 1101 100.0%
Les arguments supplémentaires fournis à tapply
sont en fait fournis directement à la fonction appelée.
tapply(d$bricol, d$sexe, freq, total = TRUE)
$Homme
Frequency table
Class: factor (numeric)
Length: 899
Levels: 2: Non, Oui
Available: 899 (100%, NA: 0 = 0%)
Unique: 2
Item Count Percent Cum. Count Cum. Percent
--- ------ ------- --------- ------------ --------------
1 Oui 515 57.29% 515 57.29%
2 Non 384 42.71% 899 100.00%
$Femme
Frequency table
Class: factor (numeric)
Length: 1,101
Levels: 2: Non, Oui
Available: 1,101 (100%, NA: 0 = 0%)
Unique: 2
Item Count Percent Cum. Count Cum. Percent
--- ------ ------- --------- ------------ --------------
1 Non 763 69.3% 763 69.3%
2 Oui 338 30.7% 1101 100.0%
La fonction by
est un équivalent (pour les tableaux de données) de tapply
. La présentation des résultats diffère légèrement.
tapply(d$age, d$sexe, mean)
Homme Femme
48.16129 48.15350
by(d$age, d$sexe, mean)
d$sexe: Homme
[1] 48.16129
---------------------------------------------
d$sexe: Femme
[1] 48.1535
Extension dplyr
On utilisera tout simplement la fonction filter
.
library(dplyr)
<- as_tibble(hdv2003)
tbl <- tbl %>% filter(sexe == "Homme", age < 30) hommes_jeunes
Voir le chapitre dédié à dplyr pour plus de détails.
Extension data.table
Il suffit d’indiquer la condition entre crochets.
library(data.table)
<- as.data.table(hdv2003)
dt <- dt[sexe == "Hommes" & age < 30] hommes_jeunes
Il est également possible d’utiliser la fonction subset
sur un data.table
.
<- subset(dt, sexe == "Hommes" & age < 30) hommes_jeunes
Voir le chapitre dédié à data.table pour plus de détails.