Chapitre 2 Les vecteurs et les facteurs

2.1 Les vecteurs

Imaginons maintenant que nous avons interrogé dix personnes au hasard dans la rue et que nous avons relevé pour chacune d’elle sa taille (en centimètre), son nom et son niveau d’étude.

Un ensemble de données de même nature constituent pour R un vecteur (en anglais vector) et se construit à l’aide de fonction nommée c.

Vecteur de type numérique

tailles <- c(167, 192, 173, 174, 172, 167, 171, 185, 163, 170)
tailles
 [1] 167 192 173 174 172 167 171 185 163 170
str(tailles)
 num [1:10] 167 192 173 174 172 167 171 185 163 170

Vecteur de type caractère

nom <- c("Benjamin", "Hugo", "Emma", "Alex", "Tom", "Axel", "Alice", "Martin", 
    "Robin", "Enzo")
nom
 [1] "Benjamin" "Hugo"     "Emma"     "Alex"     "Tom"      "Axel"    
 [7] "Alice"    "Martin"   "Robin"    "Enzo"    
str(nom)
 chr [1:10] "Benjamin" "Hugo" "Emma" "Alex" "Tom" "Axel" "Alice" ...

Voici un autre vecteur de type caractère

etud <- c("Bac+2", "Bac", "Master", "Bac", "Bac", "DEA", "Doctorat", "Doctorat", 
    "Bac", "Master")

Vecteur de type logique

Supposons que vous voulez savoir si un individu est fumeur ou pas. Puisqu’il s’agit d’un caractère binaire (vrai, faux), on peut utiliser un vecteur logique :

fum <- c(FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE)
fum
 [1] FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE
str(fum)
 logi [1:10] FALSE FALSE TRUE FALSE FALSE TRUE ...

Opérateurs logiques

Opérateur logique Signification
& et
| ou
! négation

Voici une illustartion:

x <- c(FALSE, TRUE, FALSE)
y <- c(FALSE, TRUE, TRUE)
x & y
[1] FALSE  TRUE FALSE
x | y
[1] FALSE  TRUE  TRUE
!x
[1]  TRUE FALSE  TRUE

Remaque: On peut très bien appliquer des opérations arithmétiques sur un objet logique. Dans ce cas, R transforme les FALSE en 0 et les TRUE en 1. Voici un exemple

fum + c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
 [1] 0 0 1 0 0 1 0 0 0 1

Opérateurs de comparaison

Opérateur de comparaison Signification
== égal à
!= différent de
> strictement supérieur à
< strictement inférieur à
>= supérieur ou égal à
<= inférieur ou égal à

Voici une illustartion:

x <- c(1, 3, -1, 0)
y <- c(1, 0, 3, 0)
x == y
[1]  TRUE FALSE FALSE  TRUE
x != y
[1] FALSE  TRUE  TRUE FALSE
x < y
[1] FALSE FALSE  TRUE FALSE
x >= y
[1]  TRUE  TRUE FALSE  TRUE

Indexation

On peut accéder à un élément particulier du vecteur en faisant suivre le nom du vecteur de crochets contenant le numéro de l’élément désiré. Cette opération s’appelle l’indexation. Par exemple

etud[2]
[1] "Bac"
etud[c(2, 6)]
[1] "Bac" "DEA"
etud[-c(2, 6)]
[1] "Bac+2"    "Master"   "Bac"      "Bac"      "Doctorat" "Doctorat"
[7] "Bac"      "Master"  

Modifier les éléments d’un vecteur

On peut aussi modifier un élement particulier du vecteur par indexation. Par exemple

etud[2] <- "DEA"
etud
 [1] "Bac+2"    "DEA"      "Master"   "Bac"      "Bac"      "DEA"     
 [7] "Doctorat" "Doctorat" "Bac"      "Master"  

Voici un autre exemple

etud[c(2, 6)] <- c("Bac", "Master")
etud
 [1] "Bac+2"    "Bac"      "Master"   "Bac"      "Bac"      "Master"  
 [7] "Doctorat" "Doctorat" "Bac"      "Master"  

Indexation logique

On peut aussi accéder à des éléments d’un vecteur en faisant suivre le nom du vecteur de crochets contenant un vecteur logique. Cette opération s’appelle l’indexation logique.

Par exemple, supposons que l’on souhaite savoir le nom des individus qui fument. Nous pouvons effectuer ce genre de tâche en tapant simplement

nom[fum]
[1] "Emma" "Axel" "Enzo"

Voici d’autres exemples d’utilisation de l’indexation logique:

nom[tailles >= 172]
[1] "Hugo"   "Emma"   "Alex"   "Tom"    "Martin"
sum(tailles >= 172)
[1] 5
nom[etud != "Bac"]
[1] "Benjamin" "Emma"     "Axel"     "Alice"    "Martin"   "Enzo"    
nom[tailles >= 172 & tailles < 180]
[1] "Emma" "Alex" "Tom" 
nom[tailles >= 172 & !fum]
[1] "Hugo"   "Alex"   "Tom"    "Martin"

Une autre possibilité pour faire les indexations logique est d’utliser la fonction subset (si on n’aime pas les crochets !)

subset(nom, tailles >= 172 & !fum)
[1] "Hugo"   "Alex"   "Tom"    "Martin"

R est un langage vectoriel

On peut effectuer des opérations arithmétiques simples directement sur des vecteurs

x <- c(2, 5.5, 6)
y <- c(8, 3, 4)
x + y
[1] 10.0  8.5 10.0
x^y
[1]  256.00  166.38 1296.00
2 * (x + (y + 1)/log(x + 1)) - x
[1] 18.384  9.774 11.139
log(tailles)
 [1] 5.1180 5.2575 5.1533 5.1591 5.1475 5.1180 5.1417 5.2204 5.0938 5.1358
exp(tailles)
 [1] 3.3665e+72 2.4240e+83 1.3581e+75 3.6918e+75 4.9963e+74 3.3665e+72
 [7] 1.8380e+74 2.2104e+80 6.1660e+70 6.7618e+73
tailles^2
 [1] 27889 36864 29929 30276 29584 27889 29241 34225 26569 28900

L’exemple suivant calcule l’indice de masse corporelle à partir de la taille et du poids

tailles <- c(167, 192, 173, 174, 172, 167, 171, 185, 163, 170)
poids <- c(86, 74, 83, 50, 78, 66, 66, 51, 50, 55)
imc <- poids/((tailles/100)^2)
imc
 [1] 30.837 20.074 27.732 16.515 26.366 23.665 22.571 14.901 18.819 19.031

Règle de recyclage

Si les deux objets intervenant dans l’opération ne sont pas de mêmes tailles, la règle de recyclage s’applique. R recycle l’objet le plus court assez de fois pour arriver à un objet de longueur égale à l’objet le plus long. Voici des exemples:

tailles + 20
 [1] 187 212 193 194 192 187 191 205 183 190
tailles + c(0, 20)
 [1] 167 212 173 194 172 187 171 205 163 190

Si la longueur du vecteur le plus long n’est pas un multiple du plus court, un avertissement est donné:

tailles + c(0, 20, 1)
Warning in tailles + c(0, 20, 1): longer object length is not a multiple of
shorter object length
 [1] 167 212 174 174 192 168 171 205 164 170

Valeur manquante : NA

Imaginons que la deuxième personne interrogée n’ait pas voulu nous répondre. Nous avons alors dans notre vecteur une valeur manquante. Celle-ci est symbolisée dans R par le code NA (not available)

tailles2 <- c(167, NA, 173, 174, 172, 167, 171, 185, 163, 170)
tailles2
 [1] 167  NA 173 174 172 167 171 185 163 170

Attention, a ne pas confondre : NA n’est pas la même chose que NaN qui signifie plutôt “Not a Number”.

0/0
[1] NaN

Combiner des vecteurs

Dans le cas où nous interrogeant 10 autres personnes, on peut les ajouter à ‘tailles’

Tailles <- c(tailles, 126, 177, 159, 143, 161, 180, 169, 159, 185, 160)
Tailles
 [1] 167 192 173 174 172 167 171 185 163 170 126 177 159 143 161 180 169
[18] 159 185 160

On peut remarquer la présence de nombres entre crochets au début de chaque ligne. Ces nombres indiquent la position du premier élément de la ligne dans notre vecteur. Ainsi, 159 en début de deuxième ligne est le 18 élément du vecteur.

Voici un autre exmple

tailles1 <- tailles
tailles2 <- c(126, 177, 159, 143, 161, 180, 169, 159, 185, 160)
Tailles <- c(tailles1, tailles1)
Tailles
 [1] 167 192 173 174 172 167 171 185 163 170 167 192 173 174 172 167 171
[18] 185 163 170

Rappelons-nous que tous les éléments d’un vecteur doivent être du même type. Que se passe-t-il si nous combinons des objets de type différent ?

c(tailles, "Ben")
 [1] "167" "192" "173" "174" "172" "167" "171" "185" "163" "170" "Ben"
c(tailles, TRUE)
 [1] 167 192 173 174 172 167 171 185 163 170   1
c("Ben", TRUE)
[1] "Ben"  "TRUE"

2.2 Les facteurs

Pour encoder les réponses à une question ferme (question ne laissant à son destinataire que des choix prédéfinis), on utilisera un type particulier de vecteurs appelés facteurs. De façon générale, en statistique, un facteur est typiquement utilisé pour stocker les valeurs observées d’une variable qualitative ou catégorique.

Les facteurs prennent leurs valeurs dans un ensemble de modalités prédéfinies (niveaux), et ne peuvent en prendre d’autres. Pour créer un facteur, on utilise la fonction factor. Voici un exemple.

sexe <- factor(c("H", "H", "F", "H", "H", "F", "F", "F"))
sexe
[1] H H F H H F F F
Levels: F H

Les niveaux d’un facteur

sexe et un objet de type facteur qui ne peut prendre que les niveaux ,ou modalités, “H” et “F”. Pour connaitre les niveaux d’un facteur, on utilise la fonction levels.

levels(sexe)
[1] "F" "H"

Examinons la structure de ce facteur avec la fonction str

str(sexe)
 Factor w/ 2 levels "F","H": 2 2 1 2 2 1 1 1

Notez que R affiche les niveaux d’un facteur sous forme de caractère. Cependant, en interne, R les stocke sous forme d’entiers (dans notre exemple 2=“H” et 1=“F”).

Par défaut, les niveaux d’un facteur nouvellement créés sont l’ensemble des valeurs uniques du vecteur utilisé.

L’option levels permets de prédéfinir les niveaux d’un facteur. Dans l’exemple suivant, de représente le résultat du lancement d’un dé huit fois.

de <- factor(c(3, 2, 2, 1, 3, 1, 3, 1), levels = c(1, 2, 3, 4, 5, 6))
de
[1] 3 2 2 1 3 1 3 1
Levels: 1 2 3 4 5 6
str(de)
 Factor w/ 6 levels "1","2","3","4",..: 3 2 2 1 3 1 3 1

Modifier les valeurs d’un facteur

On peut modifier la valeur d’un facteur facilement par indexation comme pour un vecteur. Exemples:

sexe[1] <- "F"
sexe
[1] F H F H H F F F
Levels: F H
de[c(2, 3)] <- c(6, 5)
de
[1] 3 6 5 1 3 1 3 1
Levels: 1 2 3 4 5 6

Si on modifie la valeur d’un facteur en utilisant une valeur qui ne fait pas partie de ces niveaux, on obtient un message d’erreur et une valeur manquante est utilisée à la place. Exemple:

sexe[1] <- "Homme"
Warning in `[<-.factor`(`*tmp*`, 1, value = "Homme"): invalid factor level,
NA generated
sexe
[1] <NA> H    F    H    H    F    F    F   
Levels: F H
sexe[1] <- "H"
sexe
[1] H H F H H F F F
Levels: F H

Modifier les niveaux d’un facteur

On peut modifier les niveaux facilement en utilisant la fonction levels.

levels(sexe)
[1] "F" "H"
levels(sexe)[1] <- "Femme"
sexe
[1] H     H     Femme H     H     Femme Femme Femme
Levels: Femme H

Voici un autre exemple

levels(sexe) <- c("Femme", "Homme")
sexe
[1] Homme Homme Femme Homme Homme Femme Femme Femme
Levels: Femme Homme

et encore un autre

levels(de) <- c("Face 1", "Face 2", "Face 3", "Face 4", "Face 5", "Face 6")
de
[1] Face 3 Face 6 Face 5 Face 1 Face 3 Face 1 Face 3 Face 1
Levels: Face 1 Face 2 Face 3 Face 4 Face 5 Face 6

L’ordre des niveaux

En interne, par défaut, les niveaux d’un facteur nouvellement créés sont classés par ordre alphanumérique croissant ou selon l’ordre qui figure dans l’option levels. Cet ordre est utilisé chaque fois que le facteur est employé.

sexe <- factor(c("H", "H", "F", "H", "H", "F", "F", "F"), levels = c("H", "F"))
sexe
[1] H H F H H F F F
Levels: H F
summary(sexe)
H F 
4 4 
sexe <- factor(c("H", "H", "F", "H", "H", "F", "F", "F"))
sexe
[1] H H F H H F F F
Levels: F H
summary(sexe)
F H 
4 4 

On peut modifier l’ordre des niveaux d’un facteur existant en utilisant l’option levels:

sexe <- factor(sexe, levels = c("H", "F"))
sexe
[1] H H F H H F F F
Levels: H F
summary(sexe)
H F 
4 4 

Découper une variable numérique en classes

Une opération relativement courante consiste à découper une variable numérique en classes. On utilise pour cela la fonction cut. Voici un exemple

poids <- c(86, 74, 83, 51, 78, 66, 66, 51, 50, 55, 55, 80, 77, 78, 80, 88, 68, 
    69, 74)
poidsC <- cut(poids, breaks = c(50, 60, 70, 80, 90))
poidsC
 [1] (80,90] (70,80] (80,90] (50,60] (70,80] (60,70] (60,70] (50,60]
 [9] <NA>    (50,60] (50,60] (70,80] (70,80] (70,80] (70,80] (80,90]
[17] (60,70] (60,70] (70,80]
Levels: (50,60] (60,70] (70,80] (80,90]

2.3 Exercices

Exercice 1

Construire le vecteur x suivant :

[1] 120 134 256  12
x <- c(120, 134, 256, 12)

Utiliser ce vecteur x pour générer les deux vecteurs suivants :

[1] 220 234 356 112
[1] 240 268 512  24
x + 100
x * 2

Exercice 2

On a demandé à 4 ménages le revenu des deux conjoints, et le nombre de personnes du ménage :

conjoint1 <- c(1200, 1180, 1750, 2100)
conjoint2 <- c(1450, 1870, 1690, 0)
nb_personnes <- c(4, 2, 3, 2)

Calculer le revenu total de chaque ménage, puis diviser par le nombre de personnes pour obtenir le revenu par personne de chaque ménage.

revenu_total <- conjoint1 + conjoint2
revenu_total/nb_personnes

Exercice 3

Soit x un vecteur contenant les valeurs :

1 18 2 1 5 2 6 1 12 3 13 8 20 1 5 7 7 4 14 10

Écrire une expression R permettant d’extraire les éléments suivants.

  1. Le deuxième élément.
  2. Les cinq premiers éléments.
  3. Les éléments strictement supérieurs à 14.
  4. Tous les éléments sauf les éléments en positions 6, 10 et 12
x <- c(1, 18, 2, 1, 5, 2, 6, 1, 12, 3, 13, 8, 20, 1, 5, 7, 7, 4, 14, 10)
x[2]
x[1:5]
x[x > 14]
x[-c(6, 10, 12)]