Partie 5 Manipulation de données▲
Cette partie est un peu aride et pas forcément très intuitive. Elle aborde cependant la base de tous les traitements et manipulations de données sous R, et mérite donc que l'on s'y arrête un moment, ou que l'on y revienne un peu plus tard en cas de saturation…
Variables▲
Le type d'objet utilisé par R pour stocker des tableaux de données s'appelle un data frame. Celui-ci comporte des observations en ligne et des variables en colonnes. On accède aux variables d'un data frame avec l'opérateur $.
Dans ce qui suit, on travaillera sur le jeu de données tiré de l'enquête Histoire de vie, fourni avec l'extension rgrs et décrit dans l'annexe B.3.3B.3.3 Le jeu de données hdv2003.
R>
library
(rgrs)
R>
data
(hdv2003)
R>
d <-
hdv2003
Mais aussi sur le jeu de données tiré du recensement 1999, décrit dans l'annexe B.3.4B.3.4 Le jeu de données rp99 :
R>
data
(rp99)
Types de variables▲
On peut considérer qu'il existe quatre types de variables dans R :
- les variables numériques, ou quantitatives ;
- les facteurs, qui prennent leurs valeurs dans un ensemble défini de modalités. Elles correspondent en général aux questions fermées d'un questionnaire ;
- les variables caractères, qui contiennent des chaînes de caractères plus ou moins longues. On les utilise pour les questions ouvertes ou les champs libres ;
- les variables booléennes, qui ne peuvent prendre que la valeur vrai (
TRUE
) ou faux (FALSE
). On les utilise dans R pour les calculs et les recodages.
Pour connaître le type d'une variable donnée, on peut utiliser la fonction class.
Résultat de class |
Type de variable |
---|---|
factor |
Facteur |
integer |
Numérique |
double |
Numérique |
numeric |
Numérique |
character |
Caractères |
logical |
Booléenne |
2.
3.
4.
5.
6.
R>
class
(d$
age)
[
1
]
"integer"
R>
class
(d$
sexe)
[
1
]
"factor"
R>
class
(c
(TRUE
, TRUE
, FALSE
))
[
1
]
"logical"
La fonction str permet également d'avoir un listing de toutes les variables d'un tableau de données et indique le type de chacune d'elle.
Renommer des variables▲
Une opération courante lorsque l'on a importé des variables depuis une source de données externe consiste à renommer les variables importées. Sous R les noms de variables doivent être à la fois courts et explicites tout en obéissant à certaines règles décrites dans la seconde remarque de la section 2.2.1Objets simples.
On peut lister les noms des variables d'un data frame à l'aide de la fonction names :
2.
3.
4.
5.
6.
R>
names
(d)
[
1
]
"id"
"age"
"sexe"
"nivetud"
[
5
]
"poids"
"occup"
"qualif"
"freres.soeurs"
[
9
]
"clso"
"relig"
"trav.imp"
"trav.satisf"
[
13
]
"hard.rock"
"lecture.bd"
"peche.chasse"
"cuisine"
[
17
]
"bricol"
"cinema"
"sport"
"heures.tv"
Cette fonction peut également être utilisée pour renommer l'ensemble des variables. Si, par exemple on souhaitait passer les noms de toutes les variables en majuscules, on pourrait faire :
2.
3.
4.
5.
6.
7.
8.
9.
R>
d.maj <-
d
R>
names
(d.maj) <-
c
("ID"
, "AGE"
, "SEXE"
, "NIVETUD"
, "POIDS"
,
+
"OCCUP"
, "QUALIF"
, "FRERES.SOEURS"
, "CLSO"
, "RELIG"
,
+
"TRAV.IMP"
, "TRAV.SATISF"
, "HARD.ROCK"
, "LECTURE.BD"
,
+
"PECHE.CHASSE"
, "CUISINE"
, "BRICOL"
, "CINEMA"
, "SPORT"
,
+
"HEURES.TV"
)
R>
summary
(d.maj$
SEXE)
Homme Femme
899
1101
Ce type de renommage peut être utile lorsque l'on souhaite passer en revue tous les noms de variables d'un fichier importé, pour les corriger le cas échéant. Pour faciliter un peu ce travail pas forcément passionnant, on peut utiliser la fonction dput :
2.
3.
4.
5.
R>
dput
(names
(d))
c
("id"
, "age"
, "sexe"
, "nivetud"
, "poids"
, "occup"
, "qualif"
,
"freres.soeurs"
, "clso"
, "relig"
, "trav.imp"
, "trav.satisf"
,
"hard.rock"
, "lecture.bd"
, "peche.chasse"
, "cuisine"
, "bricol"
,
"cinema"
, "sport"
, "heures.tv"
)
On obtient en résultat la liste des variables sous forme de vecteur déclaré. On n'a plus alors qu'à copier/coller cette chaîne, rajouter names
(d) <-
devant, et modifier un à un les noms des variables.
Si on souhaite seulement modifier le nom d'une variable, on peut utiliser la fonction renomme.variable de l'extension rgrs. Celle-ci prend en argument le tableau de données, le nom actuel de la variable et le nouveau nom. Par exemple, si on veut renommer la variable bricol du tableau de données d en bricolage :
2.
3.
4.
R>
d <-
renomme.variable(d, "bricol"
, "bricolage"
)
R>
table
(d$
bricolage)
Non Oui
1147
853
Facteurs▲
Parmi les différents types de variables, les facteurs (factor) sont à la fois à part et très utilisés, car ils vont correspondre à la plupart des variables issues d'une question fermée dans un questionnaire.
Les facteurs prennent leurs valeurs dans un ensemble de modalités prédéfinies, et ne peuvent en prendre d'autres. La liste des valeurs possibles est donnée par la fonction levels :
2.
R>
levels
(d$
sexe)
[
1
]
"Homme"
"Femme"
Si on veut modifier la valeur du sexe du premier individu de notre tableau de données avec une valeur différente, on obtient un message d'erreur et une valeur manquante est utilisée à la place :
2.
3.
4.
R>
d$
sexe[
1
]
<-
"Chihuahua"
R>
d$
sexe[
1
]
[
1
]
<
NA
>
Levels:
Homme Femme
On peut très facilement créer un facteur à partir d'une variable de type caractères avec la commande factor :
2.
3.
4.
R>
v <-
factor
(c
("H"
, "H"
, "F"
, "H"
))
R>
v
[
1
]
H H F
H
Levels:
F
H
Par défaut, les niveaux d'un facteur nouvellement créés sont l'ensemble des valeurs de la variable caractères, ordonnées par ordre alphabétique. Cet ordre des niveaux est utilisé à chaque fois que l'on emploie des fonctions comme table, par exemple :
2.
3.
4.
R>
table
(v)
v
F
H
1
3
On peut modifier cet ordre au moment de la création du facteur en utilisant l'option levels :
2.
3.
4.
5.
R>
v <-
factor
(c
("H"
, "H"
, "F"
, "H"
), levels
=
c
("H"
, "F"
))
R>
table
(v)
v
H F
3
1
On peut aussi modifier l'ordre des niveaux d'une variable déjà existante :
2.
3.
4.
5.
6.
7.
8.
9.
10.
R>
d$
qualif <-
factor
(d$
qualif, levels
=
c
("Ouvrier specialise"
,
+
"Ouvrier qualifie"
, "Employe"
, "Technicien"
, "Profession intermediaire"
,
+
"Cadre"
, "Autre"
))
R>
table
(d$
qualif)
Ouvrier specialise Ouvrier qualifie Employe
203
292
594
Technicien Profession intermediaire Cadre
86
160
260
Autre
58
Par défaut, les valeurs manquantes ne sont pas considérées comme un niveau de facteur. On peut cependant les transformer en niveau en utilisant l'option exclude=
NULL
. Ceci signifie cependant qu'elles ne seront plus considérées comme manquantes par R :
2.
3.
4.
5.
6.
R>
summary
(d$
trav.satisf)
Satisfaction Insatisfaction Equilibre NA
's
480
117
451
952
R>
summary
(factor
(d$
trav.satisf, exclude =
NULL
))
Satisfaction Insatisfaction Equilibre <
NA
>
480
117
451
952
Indexation▲
L'indexation est l'une des fonctionnalités les plus puissantes, mais aussi les plus difficiles à maîtriser de R. Il s'agit d'opérations permettant de sélectionner des sous-ensembles d'observations et/ou de variables en fonction de différents critères. L'indexation peut porter sur des vecteurs, des matrices ou des tableaux de données.
Le principe est toujours le même : on indique, entre crochets et à la suite du nom de l'objet à indexer, une série de conditions indiquant ce que l'on garde ou non. Ces conditions peuvent être de différents types.
Indexation directe▲
Le mode le plus simple d'indexation consiste à indiquer la position des éléments à conserver. Dans le cas d'un vecteur cela permet de sélectionner un ou plusieurs éléments de ce vecteur.
Soit le vecteur suivant :
R>
v <-
c
("a"
, "b"
, "c"
, "d"
, "e"
, "f"
, "g"
)
Si on souhaite le premier élément du vecteur, on peut faire :
R>
v[
1
]
[
1
]
"a"
Si on souhaite les trois premiers éléments ou les éléments 2, 6 et 7 :
2.
3.
4.
R>
v[
1
:
3
]
[
1
]
"a"
"b"
"c"
R>
v[
c
(2
, 6
, 7
)]
[
1
]
"b"
"f"
"g"
Si on veut le dernier élément :
R>
v[
length
(v)]
[
1
]
"g"
Dans le cas de matrices ou de tableaux de données, l'indexation prend deux arguments séparés par une virgule : le premier concerne les lignes et le second les colonnes. Ainsi, si on veut l'élément correspondant à la troisième ligne et à la cinquième colonne du tableau de données d :
R>
d[
3
, 5
]
[
1
]
3994.102
On peut également indiquer des vecteurs :
2.
3.
4.
5.
R>
d[
1
:
3
, 1
:
2
]
id age
1
1
28
2
2
23
3
3
59
Si on laisse l'un des deux critères vide, on sélectionne l'intégralité des lignes ou des colonnes. Ainsi si l'on veut seulement la cinquième colonne ou les deux premières lignes :
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.
R>
d[
, 5
]
[
1
]
2634.3982
9738.3958
3994.1025
5731.6615
4329.0940
8674.6994
[
7
]
6165.8035
12891.6408
7808.8721
2277.1605
704.3227
6697.8682
[
13
]
7118.4659
586.7714
11042.0774
9958.2287
4836.1393
1551.4846
[
19
]
3141.1572
27195.8378
14647.9983
8128.0603
1281.9156
11663.3383
[
25
]
8780.2614
1700.8437
6662.8375
3359.4690
8536.1101
10620.5259
[
31
]
5264.2953
14161.7597
1339.6196
9243.9153
4512.2959
7871.6452
[
37
]
1356.9621
7626.3300
1630.2746
2196.2485
5605.9846
8841.2960
[
43
]
9113.5378
2267.5912
7706.2944
2446.5111
8118.2639
10751.5037
[
49
]
831.8599
6591.6440
1936.8826
834.3845
3432.5286
11354.8932
[
55
]
9292.9762
6344.1227
4899.9404
4766.8652
3462.8121
23732.4853
[
61
]
833.8428
8529.4403
3190.3680
2423.1052
5945.9929
14991.8652
[
67
]
2062.1124
5702.0623
20604.2642
2634.4861
[
reached getOption
("max.print"
) --
omitted 1930
entries ]]
R>
d[
1
:
2
, ]
id age sexe nivetud
1
1
28
Femme Enseignement superieur y compris technique superieur
2
2
23
Femme <
NA
>
poids occup qualif freres.soeurs clso
1
2634.398
Exerce une profession Employe 8
Oui
2
9738.396
Etudiant, eleve <
NA
>
2
Oui
relig trav.imp trav.satisf hard.rock
1
Ni croyance ni appartenance Peu important Insatisfaction Non
2
Ni croyance ni appartenance <
NA
>
<
NA
>
Non
lecture.bd peche.chasse cuisine bricol cinema sport heures.tv
1
Non Non Oui Non Non Non 0
2
Non Non Non Non Oui Oui 1
Enfin, si on préfixe les arguments avec le signe « - », ceci signifie « tous les éléments sauf ceux indiqués ». Si, par exemple on veut tous les éléments de v sauf le premier :
R>
v[-
1
]
[
1
]
"b"
"c"
"d"
"e"
"f"
"g"
Bien sûr, tous ces critères se combinent et on peut stocker le résultat dans un nouvel objet. Dans cet exemple d2 contiendra les trois premières lignes de d,mais sans les colonnes 2, 6 et 8.
R>
d2 <-
d[
1
:
3
, -
c
(2
, 6
, 8
)]
Indexation par nom▲
Un autre mode d'indexation consiste à fournir non pas un numéro, mais un nom sous forme de chaîne de caractères. On l'utilise couramment pour sélectionner les variables d'un tableau de données. Ainsi, les deux fonctions suivantes sont équivalentes :
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.
R>
d$
clso
[
1
]
Oui Oui Non Non Oui
[
6
]
Non Oui Non Oui Non
[
11
]
Oui Oui Oui Oui Oui
[
16
]
Non Non Non Non Non
[
21
]
Oui Oui Non Non Non
[
26
]
Oui Non Non Non Oui
[
31
]
Non Oui Oui Non Non
[
36
]
Oui Oui Non Non Oui
[
41
]
Non Non Oui Non Non
[
46
]
Non Non Oui Oui Non
[
51
]
Non Non Oui Non Oui
[
56
]
Oui Non Non Oui Non
[
61
]
Non Oui Oui Oui Oui
[
66
]
Non Oui Non Non Ne sait pas
[
reached getOption
("max.print"
) --
omitted 1930
entries ]]
Levels:
Oui Non Ne sait pas
R>
d[
, "clso"
]
[
1
]
Oui Oui Non Non Oui
[
6
]
Non Oui Non Oui Non
[
11
]
Oui Oui Oui Oui Oui
[
16
]
Non Non Non Non Non
[
21
]
Oui Oui Non Non Non
[
26
]
Oui Non Non Non Oui
[
31
]
Non Oui Oui Non Non
[
36
]
Oui Oui Non Non Oui
[
41
]
Non Non Oui Non Non
[
46
]
Non Non Oui Oui Non
[
51
]
Non Non Oui Non Oui
[
56
]
Oui Non Non Oui Non
[
61
]
Non Oui Oui Oui Oui
[
66
]
Non Oui Non Non Ne sait pas
[
reached getOption
("max.print"
) --
omitted 1930
entries ]]
Levels:
Oui Non Ne sait pas
Là aussi on peut utiliser un vecteur pour sélectionner plusieurs noms et récupérer un « sous-tableau » de données :
R>
d2 <-
d[
, c
("id"
, "sexe"
, "age"
)]
Les noms peuvent également être utilisés pour les observations (lignes) d'un tableau de données si celles-ci ont été munies d'un nom avec la fonction row.names. Par défaut les noms de ligne sont leur numéro d'ordre, mais on peut leur assigner comme nom la valeur d'une variable d'identifiant. Ainsi, on peut assigner aux lignes du jeu de données rp99 le nom des communes correspondantes :
R>
row.names
(rp99) <-
rp99$
nom
On peut alors accéder directement aux communes en donnant leur nom :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
R>
rp99[
c
("VILLEURBANNE"
, "OULLINS"
), ]
nom code pop.act pop.tot pop15 nb.rp agric
VILLEURBANNE VILLEURBANNE 69266
57252
124152
103157
55136
0.02095997
OULLINS OULLINS 69149
11849
25186
20880
11091
0.10127437
artis cadres interm empl ouvr retr
VILLEURBANNE 5.143925
13.13841
25.72312
31.41550
23.07343
36.65374
OULLINS 4.818972
10.20339
27.42847
31.53009
24.37336
41.54781
tx.chom etud dipl.sup dipl.aucun proprio hlm
VILLEURBANNE 14.82394
15.50646
9.744370
16.90045
37.61970
23.33684
OULLINS 10.64225
10.62739
7.624521
14.31513
51.51023
14.56136
locataire maison
VILLEURBANNE 32.76988
6.532937
OULLINS 29.91615
17.708052
Par contre, il n'est pas possible d'utiliser directement l'opérateur « - » comme pour l'indexation directe. On doit effectuer une pirouette un peu compliquée utilisant la fonction which. Celle-ci renvoie les positions des éléments satisfaisant une condition. On peut ainsi faire :
2.
3.
R>
which
(names
(d) ==
"qualif"
)
[
1
]
7
R>
d2 <-
d[
, -
which
(names
(d) ==
"qualif"
)]
pour sélectionner toutes les colonnes sauf celle qui s'appelle qualif.
Indexation par conditions▲
Tests et conditions
Une condition est une expression logique dont le résultat est soit TRUE
(vrai) soit FALSE
(faux).
Une condition comprend la plupart du temps un opérateur de comparaison. Les plus courants sont les suivants :
Opérateur |
Signification |
---|---|
égal à |
|
différent de |
|
strictement supérieur à |
|
strictement inférieur à |
|
supérieur ou égal à |
|
inférieur ou égal à |
Voyons tout de suite un exemple :
2.
3.
4.
5.
6.
7.
8.
9.
R>
d$
sexe ==
"Homme"
[
1
]
FALSE
FALSE
TRUE
TRUE
FALSE
FALSE
FALSE
TRUE
FALSE
TRUE
FALSE
[
12
]
TRUE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
TRUE
FALSE
FALSE
TRUE
[
23
]
FALSE
FALSE
FALSE
TRUE
FALSE
TRUE
TRUE
TRUE
TRUE
TRUE
TRUE
[
34
]
TRUE
FALSE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
TRUE
TRUE
FALSE
[
45
]
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
TRUE
FALSE
TRUE
[
56
]
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
TRUE
TRUE
TRUE
TRUE
FALSE
[
67
]
TRUE
TRUE
FALSE
FALSE
[
reached getOption
("max.print"
) --
omitted 1930
entries ]]
Que s'est-il passé ? Nous avons fourni à R une condition qui signifie « la valeur de la variable sexe vaut "Homme" ». Et il nous a renvoyé un vecteur avec autant d'éléments qu'il y a d'observations dans d, et dont la valeur est TRUE
si l'observation correspond à un homme, et FALSE
dans les autres cas.
Prenons un autre exemple. On n'affichera cette fois que les premiers éléments de notre variable d'intérêt à l'aide de la fonction head :
2.
3.
4.
R>
head
(d$
age)
[
1
]
28
23
59
34
71
35
R>
head
(d$
age >
40
)
[
1
]
FALSE
FALSE
TRUE
FALSE
TRUE
FALSE
On voit bien ici qu'à chaque élément du vecteur d$
age dont la valeur est supérieure à 40 correspond un élément TRUE
dans le résultat de la condition.
On peut combiner ou modifier des conditions à l'aide des opérateurs logiques habituels :
Comment les utilise-t-on ? Voyons tout de suite des exemples. Supposons que je veuille déterminer quels sont dans mon échantillon les hommes ouvriers spécialisés :
2.
3.
4.
5.
6.
7.
8.
9.
R>
d$
sexe ==
"Homme"
&
d$
qualif ==
"Ouvrier specialise"
[
1
]
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
[
12
]
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
[
23
]
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
NA
[
34
]
NA
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
[
45
]
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
[
56
]
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
NA
FALSE
NA
FALSE
FALSE
[
67
]
FALSE
FALSE
FALSE
FALSE
[
reached getOption
("max.print"
) --
omitted 1930
entries ]]
Si je souhaite identifier les personnes qui bricolent ou qui font la cuisine :
2.
3.
4.
5.
6.
7.
8.
9.
R>
d$
bricol ==
"Oui"
|
d$
cuisine ==
"Oui"
[
1
]
TRUE
FALSE
FALSE
TRUE
FALSE
FALSE
TRUE
TRUE
FALSE
FALSE
TRUE
[
12
]
TRUE
TRUE
TRUE
TRUE
FALSE
TRUE
TRUE
FALSE
FALSE
TRUE
FALSE
[
23
]
TRUE
FALSE
TRUE
FALSE
TRUE
FALSE
TRUE
TRUE
TRUE
TRUE
TRUE
[
34
]
TRUE
TRUE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
[
45
]
FALSE
TRUE
TRUE
TRUE
FALSE
FALSE
TRUE
TRUE
FALSE
FALSE
FALSE
[
56
]
TRUE
FALSE
TRUE
FALSE
TRUE
TRUE
TRUE
TRUE
TRUE
FALSE
TRUE
[
67
]
TRUE
TRUE
TRUE
TRUE
[
reached getOption
("max.print"
) --
omitted 1930
entries ]]
Si je souhaite isoler les femmes qui ont entre 20 et 34 ans :
2.
3.
4.
5.
6.
7.
8.
9.
R>
d$
sexe ==
"Femme"
&
d$
age >=
20
&
d$
age <=
34
[
1
]
TRUE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
[
12
]
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
[
23
]
FALSE
FALSE
TRUE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
[
34
]
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
[
45
]
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
TRUE
FALSE
[
56
]
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
[
67
]
FALSE
FALSE
FALSE
FALSE
[
reached getOption
("max.print"
) --
omitted 1930
entries ]]
Si je souhaite récupérer les enquêtés qui ne sont pas cadres, on peut utiliser l'une des deux formes suivantes :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
R>
d$
qualif !=
"Cadre"
[
1
]
TRUE
NA
TRUE
TRUE
TRUE
TRUE
TRUE
TRUE
NA
TRUE
TRUE
[
12
]
TRUE
TRUE
NA
NA
TRUE
FALSE
NA
TRUE
TRUE
TRUE
TRUE
[
23
]
TRUE
NA
TRUE
FALSE
TRUE
TRUE
TRUE
TRUE
TRUE
TRUE
NA
[
34
]
NA
TRUE
TRUE
TRUE
NA
TRUE
FALSE
TRUE
TRUE
FALSE
FALSE
[
45
]
NA
TRUE
TRUE
NA
TRUE
FALSE
TRUE
TRUE
TRUE
NA
TRUE
[
56
]
TRUE
NA
FALSE
TRUE
NA
TRUE
NA
TRUE
NA
TRUE
TRUE
[
67
]
TRUE
TRUE
TRUE
NA
[
reached getOption
("max.print"
) --
omitted 1930
entries ]]
R>
!
(d$
qualif ==
"Cadre"
)
[
1
]
TRUE
NA
TRUE
TRUE
TRUE
TRUE
TRUE
TRUE
NA
TRUE
TRUE
[
12
]
TRUE
TRUE
NA
NA
TRUE
FALSE
NA
TRUE
TRUE
TRUE
TRUE
[
23
]
TRUE
NA
TRUE
FALSE
TRUE
TRUE
TRUE
TRUE
TRUE
TRUE
NA
[
34
]
NA
TRUE
TRUE
TRUE
NA
TRUE
FALSE
TRUE
TRUE
FALSE
FALSE
[
45
]
NA
TRUE
TRUE
NA
TRUE
FALSE
TRUE
TRUE
TRUE
NA
TRUE
[
56
]
TRUE
NA
FALSE
TRUE
NA
TRUE
NA
TRUE
NA
TRUE
TRUE
[
67
]
TRUE
TRUE
TRUE
NA
[
reached getOption
("max.print"
) --
omitted 1930
entries ]]
Lorsque l'on mélange « et » et « ou » il est nécessaire d'utiliser des parenthèses pour différencier les blocs. La condition suivante identifie les femmes qui sont soit cadres, soit employées :
2.
3.
4.
5.
6.
7.
8.
9.
R>
d$
sexe ==
"Femme"
&
(d$
qualif ==
"Employe"
|
d$
qualif ==
"Cadre"
)
[
1
]
TRUE
NA
FALSE
FALSE
TRUE
TRUE
FALSE
FALSE
NA
FALSE
TRUE
[
12
]
FALSE
TRUE
NA
NA
TRUE
FALSE
NA
FALSE
FALSE
TRUE
FALSE
[
23
]
TRUE
NA
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
[
34
]
FALSE
FALSE
TRUE
FALSE
NA
TRUE
FALSE
TRUE
FALSE
FALSE
TRUE
[
45
]
NA
FALSE
FALSE
NA
TRUE
TRUE
FALSE
TRUE
FALSE
NA
FALSE
[
56
]
FALSE
NA
TRUE
FALSE
NA
TRUE
FALSE
FALSE
FALSE
FALSE
TRUE
[
67
]
FALSE
FALSE
TRUE
NA
[
reached getOption
("max.print"
) --
omitted 1930
entries ]]
L'opérateur %in%
peut être très utile : il teste si une valeur fait partie des éléments d'un vecteur. Ainsi on pourrait remplacer la condition précédente par :
2.
3.
4.
5.
6.
7.
8.
9.
R>
d$
sexe ==
"Femme"
&
d$
qualif %in%
c
("Employe"
, "Cadre"
)
[
1
]
TRUE
FALSE
FALSE
FALSE
TRUE
TRUE
FALSE
FALSE
FALSE
FALSE
TRUE
[
12
]
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
[
23
]
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
[
34
]
FALSE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
TRUE
FALSE
FALSE
TRUE
[
45
]
FALSE
FALSE
FALSE
FALSE
TRUE
TRUE
FALSE
TRUE
FALSE
FALSE
FALSE
[
56
]
FALSE
FALSE
TRUE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
TRUE
[
67
]
FALSE
FALSE
TRUE
FALSE
[
reached getOption
("max.print"
) --
omitted 1930
entries ]]
Enfin, signalons que l'on peut utiliser les fonctions table ou summary pour avoir une idée du résultat de notre condition :
2.
3.
4.
5.
6.
7.
8.
9.
R>
table
(d$
sexe)
Homme Femme
899
1101
R>
table
(d$
sexe ==
"Homme"
)
FALSE
TRUE
1101
899
R>
summary
(d$
sexe ==
"Homme"
)
Mode FALSE
TRUE
NA
's
logical
1101
899
0
Utilisation pour l'indexation
L'utilisation des conditions pour l'indexation est assez simple : si on indexe un vecteur avec un vecteur booléen, seuls les éléments correspondant à TRUE
seront conservés.
Ainsi, si on fait :
R>
dh <-
d[
d$
sexe ==
"Homme"
, ]
on obtiendra un nouveau tableau de données comportant l'ensemble des variables de d, mais seulement les observations pour lesquelles d$
sexe vaut « Homme ».
La plupart du temps ce type d'indexation s'applique aux lignes, mais on peut aussi l'utiliser sur les colonnes d'un tableau de données. L'exemple suivant, un peu compliqué, sélectionne uniquement les variables dont le nom commence par « a » ou « s » :
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.
R>
d[
, substr
(names
(d), 0
, 1
) %in%
c
("a"
, "s"
)]
age sexe sport
1
28
Femme Non
2
23
Femme Oui
3
59
Homme Oui
4
34
Homme Oui
5
71
Femme Non
6
35
Femme Oui
7
60
Femme Non
8
47
Homme Non
9
20
Femme Non
10
28
Homme Oui
11
65
Femme Non
12
47
Homme Oui
13
63
Femme Non
14
67
Femme Non
15
76
Femme Non
16
49
Femme Non
17
62
Homme Oui
18
20
Femme Oui
19
70
Homme Non
20
39
Femme Oui
21
30
Femme Non
22
30
Homme Non
23
37
Femme Oui
[
getOption
("max.print"
) est atteint --
1977
lignes omises ]]
On peut évidemment combiner les différents types d'indexation. L'exemple suivant sélectionne les femmes de plus de 40 ans et ne conserve que les variables qualif et bricol.
R>
d2 <-
d[
d$
sexe ==
"Femme"
&
d$
age >
40
, c
("qualif"
, "bricol"
)]
Valeurs manquantes dans les conditions
Une remarque importante : quand l'un des termes d'une condition comporte une valeur manquante (NA
), le résultat de cette condition n'est pas toujours TRUE
ou FALSE
, il peut aussi être à son tour une valeur manquante.
2.
3.
4.
5.
R>
v <-
c
(1
:
5
, NA
)
R>
v
[
1
]
1
2
3
4
5
NA
R>
v >
3
[
1
]
FALSE
FALSE
FALSE
TRUE
TRUE
NA
On voit que le test NA
>
3
ne renvoie ni vrai ni faux, mais NA
.
Le résultat d'une condition peut donc comporter un grand nombre de valeurs manquantes :
2.
3.
R>
summary
(d$
trav.satisf ==
"Satisfaction"
)
Mode FALSE
TRUE
NA
's
logical
568
480
952
Une autre conséquence importante de ce comportement est que l'on ne peut pas utiliser l'opérateur ==
NA
pour tester la présence de valeurs manquantes. On utilisera à la place la fonction ad hoc is.na.
On comprendra mieux le problème avec l'exemple suivant :
2.
3.
4.
5.
6.
7.
R>
v <-
c
(1
, NA
)
R>
v
[
1
]
1
NA
R>
v ==
NA
[
1
]
NA
NA
R>
is.na
(v)
[
1
]
FALSE
TRUE
Pour compliquer encore un peu le tout, lorsque l'on utilise une condition pour l'indexation, si la condition renvoie NA
, l'élément est sélectionné, comme s'il valait TRUE
. Ceci aura donc des conséquences pour l'extraction de sous-populations, comme indiqué section 5.3.1Par indexation.
Indexation et assignation▲
Dans tous les exemples précédents, on a utilisé l'indexation pour extraire une partie d'un vecteur ou d'un tableau de données, en plaçant l'opération d'indexation à droite de l'opérateur <-
.
Mais l'indexation peut également être placée à gauche de cet opérateur. Dans ce cas, les éléments sélectionnés par l'indexation sont alors remplacés par les valeurs indiquées à droite de l'opérateur <-
.
Ceci est parfaitement incompréhensible. Prenons donc un exemple simple :
2.
3.
4.
5.
6.
R>
v <-
1
:
5
R>
v
[
1
]
1
2
3
4
5
R>
v[
1
]
<-
3
R>
v
[
1
]
3
2
3
4
5
Cette fois, au lieu d'utiliser quelque chose comme x <-
v[
1
]
, qui aurait placé la valeur du premier élément de v dans x, on a utilisé v[
1
]
<-
3
, ce qui a mis à jour le premier élément de v avec la valeur 3
.
Ceci fonctionne également pour les tableaux de données et pour les différents types d'indexation évoqués précédemment :
R>
d[
257
, "sexe"
]
<-
"Homme"
Enfin on peut modifier plusieurs éléments d'un seul coup soit en fournissant un vecteur, soit en profitant du mécanisme de recyclage. Les deux commandes suivantes sont ainsi rigoureusement équivalentes :
R>
d[
c
(257
, 438
, 889
), "sexe"
]
<-
c
("Homme"
, "Homme"
, "Homme"
)
R>
d[
c
(257
, 438
, 889
), "sexe"
]
<-
"Homme"
On commence à voir comment l'utilisation de l'indexation par conditions et de l'assignation va nous permettre de faire des recodages.
R>
d$
age[
d$
age >=
20
&
d$
age <=
30
]
<-
"20-30 ans"
R>
d$
age[
is.na
(d$
age)]
<-
"Inconnu"
Sous-populations▲
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 on souhaite isoler les hommes et les femmes :
2.
3.
4.
5.
6.
7.
8.
9.
R>
dh <-
d[
d$
sexe ==
"Homme"
, ]
R>
df
<-
d[
d$
sexe ==
"Femme"
, ]
R>
table
(d$
sexe)
Homme Femme
899
1101
R>
dim
(dh)
[
1
]
899
20
R>
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 :
2.
3.
R>
dh.25 <-
d[
d$
sexe ==
"Homme"
&
d$
age <=
25
, ]
R>
dim
(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, l'existence d'une valeur manquante dans une condition fait que celle-ci est évaluée en NA
et finalement sélectionnée par l'indexation :
2.
3.
4.
5.
6.
R>
summary
(d$
trav.satisf)
Satisfaction Insatisfaction Equilibre NA
's
480
117
451
952
R>
d.satisf <-
d[
d$
trav.satisf ==
"Satisfaction"
, ]
R>
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 que l'on n'a pas de valeurs manquantes dans les variables de la condition, soit exclure explicitement les NA
de la manière suivante :
2.
3.
R>
d.satisf <-
d[
d$
trav.satisf ==
"Satisfaction"
&
!
is.na
(d$
trav.satisf), ]
R>
dim
(d.satisf)
[
1
]
480
20
C'est notamment pour cette raison que l'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 :
R>
dh <-
subset
(d, sexe ==
"Homme"
)
R>
df
<-
subset
(d, sexe ==
"Femme"
)
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 :
R>
dh <-
subset
(d, d$
sexe ==
"Homme"
)
R>
dh <-
subset
(d, sexe ==
"Homme"
)
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 :
2.
3.
4.
5.
6.
7.
8.
9.
R>
summary
(d$
trav.satisf)
Satisfaction Insatisfaction Equilibre NA
's
480
117
451
952
R>
d.satisf <-
d[
d$
trav.satisf ==
"Satisfaction"
, ]
R>
dim
(d.satisf)
[
1
]
1432
20
R>
d.satisf <-
subset
(d, trav.satisf ==
"Satisfaction"
)
R>
dim
(d.satisf)
[
1
]
480
20
Enfin, l'utilisation de l'argument select est simplifiée pour l'expression de condition sur les colonnes. On peut ainsi spécifier les noms de variables sans guillemets et leur appliquer directement l'opérateur d'exclusion - :
R>
d2 <-
subset
(d, select
=
c
(sexe, sport))
R>
d2 <-
subset
(d, age >
25
, select
=
-
c
(id, age, bricol))
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 !
R>
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 :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
R>
tapply
(d$
bricol, d$
sexe, freq
)
$
Homme
n %
Non 384
42.7
Oui 515
57.3
NA
0
0.0
$
Femme
n %
Non 763
69.3
Oui 338
30.7
NA
0
0.0
Les arguments supplémentaires fournis à tapply sont en fait fournis directement à la fonction appelée.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
R>
tapply
(d$
bricol, d$
sexe, freq
, total =
TRUE
)
$
Homme
n %
Non 384
42.7
Oui 515
57.3
NA
0
0.0
Total 899
100.0
$
Femme
n %
Non 763
69.3
Oui 338
30.7
NA
0
0.0
Total 1101
100.0
Recodages▲
Le recodage de variables est une opération extrêmement fréquente lors du traitement d'enquête. Celui-ci utilise soit l'une des formes d'indexation décrites précédemment, soit des fonctions ad hoc de R.
On passe ici en revue différents types de recodage parmi les plus courants. Les exemples s'appuient, comme précédemment, sur l'extrait de l'enquête Histoire de vie :
R>
data
(hdv2003)
R>
d <-
hdv2003
Convertir une variable▲
Il peut arriver que l'on veuille transformer une variable d'un type dans un autre.
Par exemple, on peut considérer que la variable numérique freres.soeurs est une « fausse » variable numérique et qu'une représentation sous forme de facteur serait plus adéquate. Dans ce cas il suffit de faire appel à la fonction factor :
2.
3.
4.
R>
d$
fs.fac <-
factor
(d$
freres.soeurs)
R>
levels
(d$
fs.fac)
[
1
]
"0"
"1"
"2"
"3"
"4"
"5"
"6"
"7"
"8"
"9"
"10"
"11"
"12"
"13"
[
15
]
"14"
"15"
"16"
"18"
"22"
La conversion d'une variable caractères en facteur se fait de la même manière.
La conversion d'un facteur ou d'une variable numérique en variable caractères peut se faire à l'aide de la fonction as.character :
2.
R>
d$
fs.char <-
as.character
(d$
freres.soeurs)
R>
d$
qualif.char <-
as.character
(d$
qualif)
La conversion d'un facteur en caractères est fréquemment utilisée lors des recodages du fait qu'il est impossible d'ajouter de nouvelles modalités à un facteur. Par exemple, la première des commandes suivantes génère un message d'avertissement, tandis que les deux autres fonctionnent :
2.
3.
R>
d$
qualif[
d$
qualif ==
"Ouvrier specialise"
]
<-
"Ouvrier"
R>
d$
qualif.char <-
as.character
(d$
qualif)
R>
d$
qualif.char[
d$
qualif.char ==
"Ouvrier specialise"
]
<-
"Ouvrier"
Dans le premier cas, le message d'avertissement indique que toutes les modalités « Ouvrier specialise » de notre variable qualif ont été remplacées par des valeurs manquantes NA
.
Enfin, une variable de type caractères dont les valeurs seraient des nombres peut être convertie en variable numérique avec la fonction as.numeric. Si on souhaite convertir un facteur en variable numérique, il faut d'abord le convertir en variable de classe caractère :
R>
d$
fs.num <-
as.numeric
(as.character
(d$
fs.fac))
Découper une variable numérique en classes▲
Le premier type de recodage consiste à découper une variable de type numérique en un certain nombre de classes. On utilise pour cela la fonction cut.
Celle-ci prend, outre la variable à découper, un certain nombre d'arguments :
- breaks indique soit le nombre de classes souhaité, soit, si on lui fournit un vecteur, les limites des classes ;
- labels permet de modifier les noms de modalités attribués aux classes ;
- include.lowest et right influent sur la manière dont les valeurs situées à la frontière des classes seront incluses ou exclues ;
- dig.lab indique le nombre de chiffres après la virgule à conserver dans les noms de modalités.
Prenons tout de suite un exemple et tentons de découper notre variable age en cinq classes et de placer le résultat dans une nouvelle variable nommée age5cl :
2.
3.
4.
R>
d$
age5cl <-
cut
(d$
age, 5
)
R>
table
(d$
age5cl)
(17.9
,33.8
]
(33.8
,49.6
]
(49.6
,65.4
]
(65.4
,81.2
]
(81.2
,97.1
]
454
628
556
319
43
Par défaut R nous a bien créé cinq classes d'amplitudes égales. La première classe va de 16,9 à 32,2 ans (en fait de 17 à 32), etc.
Les frontières de classe seraient plus présentables si elles utilisaient des nombres entiers. On va donc spécifier manuellement le découpage souhaité, par tranches de 20 ans :
2.
3.
4.
R>
d$
age20 <-
cut
(d$
age, c
(0
, 20
, 40
, 60
, 80
, 100
))
R>
table
(d$
age20)
(0
,20
]
(20
,40
]
(40
,60
]
(60
,80
]
(80
,100
]
72
660
780
436
52
On aurait pu tenir compte des âges extrêmes pour la première et la dernière valeur :
2.
3.
4.
5.
6.
R>
range
(d$
age)
[
1
]
18
97
R>
d$
age20 <-
cut
(d$
age, c
(17
, 20
, 40
, 60
, 80
, 93
))
R>
table
(d$
age20)
(17
,20
]
(20
,40
]
(40
,60
]
(60
,80
]
(80
,93
]
72
660
780
436
50
Les symboles dans les noms attribués aux classes ont leur importance : ( signifie que la frontière de la classe est exclue, tandis que [ signifie qu'elle est incluse. Ainsi, (20
,40
]
signifie « strictement supérieur à 20 et inférieur ou égal à 40 ».
On remarque que du coup, dans notre exemple précédent, la valeur minimale, 17, est exclue de notre première classe, et qu'une observation est donc absente de ce découpage. Pour résoudre ce problème, on peut soit faire commencer la première classe à 16, soit utiliser l'option include.lowest
=
TRUE
:
2.
3.
4.
5.
6.
7.
8.
R>
d$
age20 <-
cut
(d$
age, c
(16
, 20
, 40
, 60
, 80
, 93
))
R>
table
(d$
age20)
(16
,20
]
(20
,40
]
(40
,60
]
(60
,80
]
(80
,93
]
72
660
780
436
50
R>
d$
age20 <-
cut
(d$
age, c
(17
, 20
, 40
, 60
, 80
, 93
), include.lowest
=
TRUE
)
R>
table
(d$
age20)
[
17
,20
]
(20
,40
]
(40
,60
]
(60
,80
]
(80
,93
]
72
660
780
436
50
On peut également modifier le sens des intervalles avec l'option right
=
FALSE
, et indiquer manuellement les noms des modalités avec labels :
2.
3.
4.
5.
6.
7.
8.
9.
R>
d$
age20 <-
cut
(d$
age, c
(16
, 20
, 40
, 60
, 80
, 93
), right
=
FALSE
, include.lowest
=
TRUE
)
R>
table
(d$
age20)
[
16
,20
) [
20
,40
) [
40
,60
) [
60
,80
) [
80
,93
]
48
643
793
454
60
R>
d$
age20 <-
cut
(d$
age, c
(17
, 20
, 40
, 60
, 80
, 93
), include.lowest
=
TRUE
,
+
labels
=
c
("<20 ans"
, "21-40 ans"
, "41-60 ans"
, "61-80 ans"
, ">80 ans"
))
R>
table
(d$
age20)
<
20
ans 21
-
40
ans 41
-
60
ans 61
-
80
ans >
80
ans
72
660
780
436
50
Enfin, l'extension rgrs propose une fonction quant.cut permettant de découper une variable numérique en un nombre de classes donné ayant des effectifs semblables. Il suffit de lui passer le nombre de classes en argument :
2.
3.
4.
R>
d$
age6cl <-
quant.cut(d$
age, 6
)
R>
table
(d$
age6cl)
[
18
,30
) [
30
,39
) [
39
,48
) [
48
,55.667
) [
55.667
,66
) [
66
,97
]
302
337
350
344
305
362
quant.cut admet les mêmes autres options que cut (include.lowest, right, labels...).
Regrouper les modalités d'une variable▲
Pour regrouper les modalités d'une variable qualitative (d'un facteur le plus souvent), on peut utiliser directement l'indexation.
Ainsi, si on veut recoder la variable qualif dans une variable qualif.reg plus « compacte », on peut utiliser :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
R>
table
(d$
qualif)
Ouvrier specialise, Ouvrier qualifie, Technicien
203
, 292
, 86
Profession intermediaire, Cadre, Employe
160
, 260
, 594
Autre
58
R>
d$
qualif.reg[
d$
qualif ==
"Ouvrier specialise"
]
<-
"Ouvrier"
R>
d$
qualif.reg[
d$
qualif ==
"Ouvrier qualifie"
]
<-
"Ouvrier"
R>
d$
qualif.reg[
d$
qualif ==
"Employe"
]
<-
"Employe"
R>
d$
qualif.reg[
d$
qualif ==
"Profession intermediaire"
]
<-
"Intermediaire"
R>
d$
qualif.reg[
d$
qualif ==
"Technicien"
]
<-
"Intermediaire"
R>
d$
qualif.reg[
d$
qualif ==
"Cadre"
]
<-
"Cadre"
R>
d$
qualif.reg[
d$
qualif ==
"Autre"
]
<-
"Autre"
R>
table
(d$
qualif.reg)
Autre Cadre Employe Intermediaire Ouvrier
58
260
594
246
495
On aurait pu représenter ce recodage de manière plus compacte, notamment en commençant par copier le contenu de qualif dans qualif.reg, ce qui permet de ne pas s'occuper de ce qui ne change pas. Il est cependant nécessaire de ne pas copier qualif sous forme de facteur, sinon on ne pourrait ajouter de nouvelles modalités. On copie donc la version caractères de qualif grâce à la fonction as.character :
2.
3.
4.
5.
6.
7.
8.
R>
d$
qualif.reg <-
as.character
(d$
qualif)
R>
d$
qualif.reg[
d$
qualif ==
"Ouvrier specialise"
]
<-
"Ouvrier"
R>
d$
qualif.reg[
d$
qualif ==
"Ouvrier qualifie"
]
<-
"Ouvrier"
R>
d$
qualif.reg[
d$
qualif ==
"Profession intermediaire"
]
<-
"Intermediaire"
R>
d$
qualif.reg[
d$
qualif ==
"Technicien"
]
<-
"Intermediaire"
R>
table
(d$
qualif.reg)
Autre Cadre Employe Intermediaire Ouvrier
58
260
594
246
495
On peut faire une version encore plus compacte en utilisant l'opérateur logique ou (|) :
2.
3.
4.
5.
6.
R>
d$
qualif.reg <-
as.character
(d$
qualif)
R>
d$
qualif.reg[
d$
qualif ==
"Ouvrier specialise"
|
d$
qualif ==
"Ouvrier qualifie"
]
<-
"Ouvrier"
R>
d$
qualif.reg[
d$
qualif ==
"Profession intermediaire"
|
d$
qualif ==
"Technicien"
]
<-
"Intermediaire"
R>
table
(d$
qualif.reg)
Autre Cadre Employe Intermediaire Ouvrier
58
260
594
246
495
Enfin, pour terminer ce petit tour d'horizon, on peut également remplacer l'opérateur | par %in%
, qui peut parfois être plus lisible :
2.
3.
4.
5.
6.
R>
d$
qualif.reg <-
as.character
(d$
qualif)
R>
d$
qualif.reg[
d$
qualif %in%
c
("Ouvrier specialise"
, "Ouvrier qualifie"
)]
<-
"Ouvrier"
R>
d$
qualif.reg[
d$
qualif %in%
c
("Profession intermediaire"
, "Technicien"
)]
<-
"Intermediaire"
R>
table
(d$
qualif.reg)
Autre Cadre Employe Intermediaire Ouvrier
58
260
594
246
495
Dans tous les cas le résultat obtenu est une variable de type caractère. On pourra la convertir en facteur par un simple :
R>
d$
qualif.reg <-
factor
(d$
qualif.reg)
Si on souhaite recoder les valeurs manquantes, il suffit de faire appel à la fonction is.na :
2.
3.
4.
5.
6.
7.
8.
R>
table
(d$
trav.satisf)
Satisfaction,Insatisfaction, Equilibre
480
, 117
, 451
R>
d$
trav.satisf.reg <-
as.character
(d$
trav.satisf)
R>
d$
trav.satisf.reg[
is.na
(d$
trav.satisf)]
<-
"Valeur manquante"
R>
table
(d$
trav.satisf.reg)
Equilibre Insatisfaction Satisfaction Valeur manquante
451
117
480
952
Variables calculées▲
La création d'une variable numérique à partir de calculs sur une ou plusieurs autres variables numériques se fait très simplement.
Supposons que l'on souhaite calculer une variable indiquant l'écart entre le nombre d'heures passées à regarder la télévision et la moyenne globale de cette variable. On pourrait alors faire :
2.
3.
4.
5.
6.
7.
8.
9.
R>
range
(d$
heures.tv, na.rm
=
TRUE
)
[
1
]
0
12
R>
mean
(d$
heures.tv, na.rm
=
TRUE
)
[
1
]
2.246566
R>
d$
ecart.heures.tv <-
d$
heures.tv -
mean
(d$
heures.tv, na.rm
=
TRUE
)
R>
range
(d$
ecart.heures.tv, na.rm
=
TRUE
)
[
1
]
-
2.246566
9.753434
R>
mean
(d$
ecart.heures.tv, na.rm
=
TRUE
)
[
1
]
4.714578e-17
Autre exemple tiré du jeu de données rp99 : si on souhaite calculer le pourcentage d'actifs dans chaque commune, on peut diviser la population active pop.act par la population totale pop.tot.
R>
rp99$
part.actifs <-
rp99$
pop.act/
rp99$
pop.tot *
100
Combiner plusieurs variables▲
La combinaison de plusieurs variables se fait à l'aide des techniques d'indexation déjà décrites précédemment. Le plus compliqué est d'arriver à formuler des conditions parfois complexes de manière rigoureuse.
On peut ainsi vouloir combiner plusieurs variables qualitatives en une seule :
2.
3.
4.
5.
6.
7.
8.
9.
10.
R>
d$
act.manuelles <-
NA
R>
d$
act.manuelles[
d$
cuisine ==
"Oui"
&
d$
bricol ==
"Oui"
]
<-
"Cuisine et Bricolage"
R>
d$
act.manuelles[
d$
cuisine ==
"Oui"
&
d$
bricol ==
"Non"
]
<-
"Cuisine seulement"
R>
d$
act.manuelles[
d$
cuisine ==
"Non"
&
d$
bricol ==
"Oui"
]
<-
"Bricolage seulement"
R>
d$
act.manuelles[
d$
cuisine ==
"Non"
&
d$
bricol ==
"Non"
]
<-
"Ni cuisine ni bricolage"
R>
table
(d$
act.manuelles)
Bricolage seulement Cuisine et Bricolage Cuisine seulement
437
416
465
Ni cuisine ni bricolage
682
On peut également combiner variables qualitatives et variables quantitatives :
2.
3.
4.
5.
6.
7.
8.
9.
10.
R>
d$
age.sexe <-
NA
R>
d$
age.sexe[
d$
sexe ==
"Homme"
&
d$
age <
40
]
<-
"Homme moins de 40 ans"
R>
d$
age.sexe[
d$
sexe ==
"Homme"
&
d$
age >=
40
]
<-
"Homme plus de 40 ans"
R>
d$
age.sexe[
d$
sexe ==
"Femme"
&
d$
age <
40
]
<-
"Femme moins de 40 ans"
R>
d$
age.sexe[
d$
sexe ==
"Femme"
&
d$
age >=
40
]
<-
"Femme plus de 40 ans"
R>
table
(d$
age.sexe)
Femme moins de
40
ans Femme plus de
40
ans Homme moins de
40
ans
376
725
315
Homme plus de
40
ans
584
Les combinaisons de variables un peu complexes nécessitent parfois un petit travail de réflexion. En particulier, l'ordre des commandes de recodage a parfois une influence dans le résultat final.
Variables scores▲
Une variable score est une variable calculée en additionnant des poids accordés aux modalités d'une série de variables qualitatives.
Pour prendre un exemple tout à fait arbitraire, imaginons que nous souhaitons calculer un score d'activités extérieures. Dans ce score on considère que le fait d'aller au cinéma « pèse » 10, celui de pêcher ou chasser vaut 30 et celui de faire du sport vaut 20. On pourrait alors calculer notre score de la manière suivante :
2.
3.
4.
5.
6.
7.
R>
d$
score.ext <-
0
R>
d$
score.ext[
d$
cinema ==
"Oui"
]
<-
d$
score.ext[
d$
cinema ==
"Oui"
]
+
10
R>
d$
score.ext[
d$
peche.chasse ==
"Oui"
]
<-
d$
score.ext[
d$
peche.chasse ==
"Oui"
]
+
30
R>
d$
score.ext[
d$
sport ==
"Oui"
]
<-
d$
score.ext[
d$
sport ==
"Oui"
]
+
20
R>
table
(d$
score.ext)
0
10
20
30
40
50
60
800
342
229
509
31
41
48
Cette notation étant un peu lourde, on peut l'alléger un peu en utilisant la fonction ifelse
. Celle-ci prend en argument une condition et deux valeurs. Si la condition est vraie, elle retourne la première valeur, sinon elle retourne la seconde.
2.
3.
4.
5.
6.
R>
d$
score.ext <-
0
R>
d$
score.ext <-
ifelse
(d$
cinema ==
"Oui"
, 10
, 0
) +
ifelse
(d$
peche.chasse ==
+
"Oui"
, 30
, 0
) +
ifelse
(d$
sport ==
"Oui"
, 20
, 0
)
R>
table
(d$
score.ext)
0
10
20
30
40
50
60
800
342
229
509
31
41
48
Vérification des recodages▲
Il est très important de vérifier, notamment après les recodages les plus complexes, que l'on a bien obtenu le résultat escompté. Les deux points les plus sensibles étant les valeurs manquantes et les erreurs dans les conditions.
Pour vérifier tout cela, le plus simple est sans doute de faire des tableaux croisés entre la variable recodée et celles ayant servi au recodage, à l'aide de la fonction table, et de vérifier le nombre de valeurs manquantes dans la variable recodée avec summary, freq ou table.
Par exemple :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
R>
d$
act.manuelles <-
NA
R>
d$
act.manuelles[
d$
cuisine ==
"Oui"
&
d$
bricol ==
"Oui"
]
<-
"Cuisine et Bricolage"
R>
d$
act.manuelles[
d$
cuisine ==
"Oui"
&
d$
bricol ==
"Non"
]
<-
"Cuisine seulement"
R>
d$
act.manuelles[
d$
cuisine ==
"Non"
&
d$
bricol ==
"Oui"
]
<-
"Bricolage seulement"
R>
d$
act.manuelles[
d$
cuisine ==
"Non"
&
d$
bricol ==
"Non"
]
<-
"Ni cuisine ni bricolage"
R>
table
(d$
act.manuelles, d$
cuisine)
Non Oui
Bricolage seulement 437
0
Cuisine et Bricolage 0
416
Cuisine seulement 0
465
Ni cuisine ni bricolage 682
0
R>
table
(d$
act.manuelles, d$
bricol)
Non Oui
Bricolage seulement 0
437
Cuisine et Bricolage 0
416
Cuisine seulement 465
0
Ni cuisine ni bricolage 682
0
Tri de tables▲
On a déjà évoqué l'existence de la fonction sort, qui permet de trier les éléments d'un vecteur.
R>
sort
(c
(2
, 5
, 6
, 1
, 8
))
[
1
]
1
2
5
6
8
On peut appliquer cette fonction à une variable, mais celle-ci ne permet que d'ordonner les valeurs de cette variable, et pas l'ensemble du tableau de données dont elle fait partie. Pour cela nous avons besoin d'une autre fonction, nommée order. Celle-ci ne renvoie pas les valeurs du vecteur triées, mais les emplacements de ces valeurs.
Un exemple pour comprendre :
R>
order
(c
(15
, 20
, 10
))
[
1
]
3
1
2
Le résultat renvoyé signifie que la plus petite valeur est la valeur située en 3e position, suivie de celle en 1re position et de celle en 2e position. Tout cela ne paraît pas passionnant à première vue, mais si on mélange ce résultat avec un peu d'indexation directe, ça devient intéressant…
2.
3.
4.
5.
6.
7.
R>
order
(d$
age)
[
1
]
162
215
346
377
511
646
852
916
1211
1213
1261
1333
1395
1447
[
15
]
1600
1774
1937
38
100
134
196
204
256
257
349
395
407
427
[
29
]
453
578
726
969
1052
1056
1077
1177
1234
1250
1342
1377
1381
1382
[
43
]
1540
1559
1607
1634
1689
1983
9
18
25
231
335
347
358
488
[
57
]
496
642
826
922
1023
1042
1156
1175
1290
1384
1464
1467
1608
1661
[
reached getOption
("max.print"
) --
omitted 1930
entries ]]
Ce que cette fonction renvoie, c'est l'ordre dans lequel on doit placer les éléments de age, et donc par extension les lignes de d, pour que la variable soit triée par ordre croissant. Par conséquent, si on fait :
R>
d.tri <-
d[
order
(d$
age), ]
alors on a trié les lignes de d par ordre d'âge croissant ! Et si on fait un petit :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
R>
head
(d.tri, 3
)
id age sexe nivetud poids occup qualif freres.soeurs
162
162
18
Homme <
NA
>
4982.964
Etudiant, eleve <
NA
>
2
215
215
18
Homme <
NA
>
4631.188
Etudiant, eleve <
NA
>
2
clso relig trav.imp trav.satisf hard.rock
162
Non Appartenance sans pratique <
NA
>
<
NA
>
Non
215
Oui Ni croyance ni appartenance <
NA
>
<
NA
>
Non
lecture.bd peche.chasse cuisine bricol cinema sport heures.tv fs.fac
162
Non Non Non Non Non Oui 3
2
215
Non Non Oui Non Oui Oui 2
2
fs.char qualif.char fs.num age5cl age20 age6cl qualif.reg
162
2
<
NA
>
2
(17.9
,33.8
]
<
20ans [
18
,30
) <
NA
>
215
2
<
NA
>
2
(17.9
,33.8
]
<
20ans [
18
,30
) <
NA
>
trav.satisf.reg ecart.heures.tv act.manuelles
162
Valeur manquante 0.7534336
Ni cuisine ni bricolage
215
Valeur manquante -
0.2465664
Cuisine seulement
age.sexe score.ext
162
Homme moins de
40
ans 20
215
Homme moins de
40
ans 30
[
getOption
("max.print"
) est atteint --
dernière ligne omises ]]
on a les caractéristiques des trois enquêtés les plus jeunes.
On peut évidemment trier par ordre décroissant en utilisant l'option decreasing=
TRUE
. On peut donc afficher les caractéristiques des trois individus les plus âgés avec :
R>
head
(d[
order
(d$
age, decreasing =
TRUE
), ]
, 3
)
Fusion de tables▲
Lorsque l'on traite de grosses enquêtes, notamment les enquêtes de l'INSEE, on a souvent à gérer des données réparties dans plusieurs tables, soit du fait de la construction du questionnaire, soit du fait de contraintes techniques (fichiers dbf ou Excel limités à 256 colonnes, par exemple).
Une opération relativement courante consiste à fusionner plusieurs tables pour regrouper tout ou partie des données dans un unique tableau.
Nous allons simuler artificiellement une telle situation en créant deux tables à partir de l'extrait de l'enquête Histoire de vie :
2.
3.
4.
5.
6.
7.
8.
9.
10.
R>
data
(hdv2003)
R>
d <-
hdv2003
R>
dim
(d)
[
1
]
2000
20
R>
d1 <-
subset
(d, select
=
c
("id"
, "age"
, "sexe"
))
R>
dim
(d1)
[
1
]
2000
3
R>
d2 <-
subset
(d, select
=
c
("id"
, "clso"
))
R>
dim
(d2)
[
1
]
2000
2
On a donc deux tableaux de données, d1 et d2, comportant chacun 2000 lignes et respectivement 3 et 2 colonnes. Comment les rassembler pour n'en former qu'un ?
Intuitivement, cela paraît simple. Il suffit de « coller » d2 à la droite de d1, comme dans l'exemple suivant.
Cela semble fonctionner. La fonction qui permet d'effectuer cette opération sous R s'appelle cbind, elle « colle » des tableaux côte à côte en regroupant leurs colonnes(18).
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
R>
cbind
(d1, d2)
id age sexe id clso
1
1
28
Femme 1
Oui
2
2
23
Femme 2
Oui
3
3
59
Homme 3
Non
4
4
34
Homme 4
Non
5
5
71
Femme 5
Oui
6
6
35
Femme 6
Non
7
7
60
Femme 7
Oui
8
8
47
Homme 8
Non
9
9
20
Femme 9
Oui
10
10
28
Homme 10
Non
11
11
65
Femme 11
Oui
12
12
47
Homme 12
Oui
13
13
63
Femme 13
Oui
14
14
67
Femme 14
Oui
[
getOption
("max.print"
) est atteint --
1986
lignes omises ]]
À part le fait que l'on a une colonne id en double, le résultat semble satisfaisant. À première vue seulement. Imaginons maintenant que nous avons travaillé sur d1 et d2, et que nous avons ordonné les lignes de d1 selon l'âge des enquêtés :
R>
d1 <-
d1[
order
(d1$
age), ]
Répétons l'opération de collage :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
R>
cbind
(d1, d2)
id age sexe id clso
162
162
18
Homme 1
Oui
215
215
18
Homme 2
Oui
346
346
18
Femme 3
Non
377
377
18
Homme 4
Non
511
511
18
Homme 5
Oui
646
646
18
Homme 6
Non
852
852
18
Femme 7
Oui
916
916
18
Femme 8
Non
1211
1211
18
Homme 9
Oui
1213
1213
18
Femme 10
Non
1261
1261
18
Homme 11
Oui
1333
1333
18
Femme 12
Oui
1395
1395
18
Homme 13
Oui
1447
1447
18
Femme 14
Oui
[
getOption
("max.print"
) est atteint --
1986
lignes omises ]]
Que constate-t-on ? La présence de la variable id en double nous permet de voir que les identifiants ne coïncident plus ! En regroupant nos colonnes, nous avons donc attribué à des individus les réponses d'autres individus.
La commande cbind ne peut en effet fonctionner que si les deux tableaux ont exactement le même nombre de lignes, et dans le même ordre, ce qui n'est pas le cas ici.
On va donc être obligé de procéder à une fusion des deux tableaux, qui va permettre de rendre à chaque ligne ce qui lui appartient. Pour cela nous avons besoin d'un identifiant qui permet d'identifier chaque ligne de manière unique et qui doit être présent dans tous les tableaux. Dans notre cas, c'est plutôt rapide, il s'agit de la variable id.
Une fois l'identifiant reconnu(19), on peut utiliser la commande merge. Celle-ci va fusionner les deux tableaux en supprimant les colonnes en double et en regroupant les lignes selon leurs identifiants :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
R>
d.complet <-
merge
(d1, d2, by
=
"id"
)
R>
d.complet
id age sexe clso
1
1
28
Femme Oui
2
2
23
Femme Oui
3
3
59
Homme Non
4
4
34
Homme Non
5
5
71
Femme Oui
6
6
35
Femme Non
7
7
60
Femme Oui
8
8
47
Homme Non
9
9
20
Femme Oui
10
10
28
Homme Non
11
11
65
Femme Oui
12
12
47
Homme Oui
13
13
63
Femme Oui
14
14
67
Femme Oui
15
15
76
Femme Oui
16
16
49
Femme Non
17
17
62
Homme Non
[
getOption
("max.print"
) est atteint --
1983
lignes omises ]]
Ici l'utilisation de la fonction est plutôt simple, car nous sommes dans le cas de figure idéal : les lignes correspondent parfaitement et l'identifiant est clairement reconnu. Parfois les choses peuvent être un peu plus compliquées :
- parfois les identifiants n'ont pas le même nom dans les deux tableaux. On peut alors les spécifier par les options by.x et by.y ;
- parfois les deux tableaux comportent des colonnes (hors identifiants) ayant le même nom. merge conserve dans ce cas ces deux colonnes, mais les renomme en les suffixant par .x, pour celles provenant du premier tableau et .y pour celles du second ;
- parfois on n'a pas d'identifiant unique préétabli, mais on en construit un à partir de plusieurs variables. On peut alors donner un vecteur en paramètres de l'option by, par exemple
by
=
c
("nom"
,"prenom"
,"date.naissance"
).
Une subtilité supplémentaire intervient lorsque les deux tableaux fusionnés n'ont pas exactement les mêmes lignes. Par défaut, merge ne conserve que les lignes présentes dans les deux tableaux :
On peut cependant modifier ce comportement avec les options all.x=
TRUE
et all.y=
TRUE
. La première option indique de conserver toutes les lignes du premier tableau. Dans ce cas merge donne une valeur NA
pour ces lignes aux colonnes provenant du second tableau. Ce qui donnerait :
all.y fait la même chose en conservant toutes les lignes du second tableau. On peut enfin décider de conserver toutes les lignes des deux tableaux en utilisant à la fois all.x=
TRUE
et all.y=
TRUE
, ce qui donne :
Parfois, l'un des identifiants est présent à plusieurs reprises dans l'un des tableaux (par exemple, lorsque l'une des tables est un ensemble de ménages et que l'autre décrit l'ensemble des individus de ces ménages). Dans ce cas les lignes de l'autre table sont dupliquées autant de fois que nécessaire :
Organiser ses scripts▲
Il ne s'agit pas ici de manipulation de données à proprement parler, mais plutôt d'une conséquence de ce qui a été vu précédemment : à mesure que recodages et traitements divers s'accumulent, votre script R risque de devenir rapidement très long et pas très pratique à éditer.
Il est très courant de répartir son travail entre différents fichiers, ce qui est rendu très simple par la fonction source. Celle-ci permet de lire le contenu d'un fichier de script et d'exécuter son contenu.
Prenons tout de suite un exemple. La plupart des scripts R commencent par charger les extensions utiles, par définir le répertoire de travail à l'aide de setwd, à importer les données, à effectuer manipulations, traitements et recodages, puis à mettre en œuvre les analyses. Prenons le fichier fictif suivant :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
library
(rgrs)
library
(foreign)
setwd
("/home/julien/r/projet"
)
## IMPORT DES DONNÉES
d1 <-
read.dbf("tab1.dbf"
)
d2 <-
read.dbf("tab2.dbf"
)
d <-
merge
(d1, d2, by
=
"id"
)
## RECODAGES
d$
tx.chomage <-
as.numeric
(d$
tx.chomage)
d$
pcs[
d$
pcs ==
"Ouvrier qualifie"
]
<-
"Ouvrier"
d$
pcs[
d$
pcs ==
"Ouvrier specialise"
]
<-
"Ouvrier"
d$
age5cl <-
cut
(d$
age, 5
)
## ANALYSES
tab <-
table
(d$
tx.chomage, d$
age5cl)
tab
chisq.test
(tab)
Une manière d'organiser notre script(20) pourrait être de placer les opérations d'import des données et celles de recodage dans deux fichiers scripts séparés. Créons alors un fichier nommé import.R dans notre répertoire de travail et copions les lignes suivantes :
2.
3.
4.
5.
6.
## IMPORT DES DONNÉES
d1 <-
read.dbf("tab1.dbf"
)
d2 <-
read.dbf("tab2.dbf"
)
d <-
merge
(d1, d2, by
=
"id"
)
Créons également un fichier recodages.R avec le contenu suivant :
2.
3.
4.
5.
6.
7.
## RECODAGES
d$
tx.chomage <-
as.numeric
(d$
tx.chomage)
d$
pcs[
d$
pcs ==
"Ouvrier qualifie"
]
<-
"Ouvrier"
d$
pcs[
d$
pcs ==
"Ouvrier specialise"
]
<-
"Ouvrier"
d$
age5cl <-
cut
(d$
age, 5
)
Dès lors, si nous rajoutons les appels à la fonction source qui vont bien, le fichier suivant sera strictement équivalent à notre fichier de départ :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
library
(rgrs)
library
(foreign)
setwd
("/home/julien/r/projet"
)
source
("import.R"
)
source
("recodages.R"
)
## ANALYSES
tab <-
table
(d$
tx.chomage, d$
age5cl)
tab
chisq.test
(tab)
Au fur et à mesure du travail sur les données, on placera les recodages que l'on souhaite conserver dans le fichier recodages.R.
Cette méthode présente plusieurs avantages :
- bien souvent, lorsque l'on effectue des recodages on se retrouve avec des variables recodées que l'on ne souhaite pas conserver. Si on prend l'habitude de placer les recodages intéressants dans le fichier recodages.R, alors il suffit d'exécuter les cinq premières lignes du fichier pour se retrouver avec un tableau de données d propre et complet ;
- on peut répartir ses analyses dans différents scripts. Il suffit alors de copier les cinq premières lignes du fichier précédent dans chacun des scripts, et on aura l'assurance de travailler sur exactement les mêmes données.
Le premier point illustre l'une des caractéristiques de R : il est rare que l'on stocke les données modifiées. En général on repart toujours du fichier source original, et les recodages sont conservés sous forme de scripts et recalculés à chaque fois que l'on recommence à travailler. Ceci offre une traçabilité parfaite du traitement effectué sur les données.
Exercices▲
? Solution
Renommer la variable clso du jeu de données hdv2003 en classes.sociales, puis la renommer en clso.
? Solution
Réordonner les niveaux du facteur clso pour que son tri à plat s'affiche de la manière suivante :
tmp
Non Ne sait pas Oui
1037
27
936
? Solution
Affichez :
- les 3 premiers éléments de la variable cinema ;
- les éléments 12 à 30 de la variable lecture.bd ;
- les colonnes 4 et 8 des lignes 5 et 12 du jeu de données hdv2003 ;
- les 4 derniers éléments de la variable age.
? Solution
Construisez les sous-tableaux suivants avec la fonction subset :
- âge et sexe des lecteurs de BD ;
- ensemble des personnes n'étant pas chômeur (variable occup), sans la variable cinema ;
- identifiants des personnes de plus de 45 ans écoutant du hard rock ;
- femmes entre 25 et 40 ans n'ayant pas fait de sport dans les douze derniers mois ;
- hommes ayant entre 2 et 4 frères et sœurs et faisant la cuisine ou du bricolage.
? Solution
Calculez le nombre moyen d'heures passées devant la télévision chez les lecteurs de BD, d'abord en construisant les sous-populations, puis avec la fonction tapply.
? Solution
Convertissez la variable freres.soeurs en variable de type caractères. Convertissez cette nouvelle variable en facteur. Puis convertissez à nouveau ce facteur en variable numérique. Vérifiez que votre variable finale est identique à la variable de départ.
? Solution
Découpez la variable freres.soeurs :
- en cinq classes d'amplitude égale ;
- en catégories « de 0 à 2 », « de 3 à 4 », « plus de 4 », avec les étiquettes correspondantes ;
- en quatre classes d'effectif équivalent ;
- d'où vient la différence d'effectifs entre les deux découpages précédents ?
? Solution
Recodez la variable trav.imp en trav.imp2cl pour obtenir les modalités « Le plus ou aussi important » et « moins ou peu important ». Vérifiez avec des tris à plat et un tableau croisé.
Recodez la variable relig en relig.4cl en regroupant les modalités « Pratiquant regulier » et « Pratiquant occasionnel » en une seule modalité « Pratiquant », et en remplaçant la modalité « NSP ou NVPR » par des valeurs manquantes. Vérifiez avec un tri croisé.
Créez une variable ayant les modalités suivantes :
- homme de plus de 40 ans lecteur de BD ;
- homme de plus de 30 ans ;
- femme faisant du bricolage ;
- autre.
Vérifier avec des tris croisés.
? Solution
Ordonner le tableau de données selon le nombre de frères et sœurs croissant. Afficher le sexe des 10 individus regardant le plus la télévision.