3 Les vecteurs
Les vecteurs sont la structure de données fondamentale dans R. Le terme «structure de données» fait référence à la manière dont les données sont stockées et organisées par R. En plus des vecteurs, les quatre structures les plus souvent utilisées sont: les facteurs, les matrices, les listes et les data frames (tableau des données). Chacune de ces structures/objets sera traitée séparément dans les chapitres suivants.
3.1 Les trois types de vecteurs
Les vecteurs stockent une liste ordonnée d’éléments, tous du même type: numérique, caractère ou logique. Un objet dont tous les éléments sont de même type est appelé simple ou atomique (atomic object, en anglais).
Numérique
Imaginons 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). On peut stocker cette information dans un seul objet à l’aide de la fonction c()
qui permet simplement de combiner ces arguments.
[1] 167 192 173 174 172 167 171 185 163 170
En réalité, R distingue deux types de numeric
: double
(ou dbl
) pour réelle et integer
(ou int
) pour entier, mais cette distinction n’a pas beaucoup d’importance. En R, par défaut, un numeric
est un double
.
Chaîne de caractères
Imaginons que nous avons aussi relevé le nom de chaque personne.
[1] "Benjamin" "Hugo" "Emma" "Alex" "Tom" "Axel"
[7] "Alice" "Martin" "Robin" "Enzo"
Logique
Supposons que nous savons aussi si un individu est fumeur ou pas. Puisqu’il s’agit d’une quantité binaire (vrai ou faux), on peut utiliser un vecteur logique pour stocker cette information:
[1] FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE FALSE TRUE
Notez qu’il est possible d’utliser T
et F
comme abréviations de TRUE
et FALSE
, respectivement.
[1] TRUE FALSE
Mais on recommande de ne pas utiliser cette abréviation, au risque d’entraîner certaines confusions.
3.2 Les carctériqtiques d’un vecteur
Nous pouvons examiner la structure d’un vecteur avec la fonction str()
. Cette fonction est essentielle à connaître et peut s’appliquer à n’importe quel objet R (pas uniquement les vecteurs). Elle indique la nature de l’objet ainsi qu’un aperçu de ce qui est stocker dedans.
num [1:10] 167 192 173 174 172 167 171 185 163 170
chr [1:10] "Benjamin" "Hugo" "Emma" "Alex" "Tom" "Axel" "Alice" "Martin" ...
logi [1:10] FALSE FALSE TRUE FALSE FALSE TRUE ...
Dans la sortie ci-dessus, on peut voir que la fonction str()
affiche bien la nature de chaque vecteur (num = numeric, chr = character, et logi = logical).
Un autre caractéristique important de chaque vecteur est sa longueur que nous pouvons obtenir grâce à la fonction length()
.
[1] 10
À ce propos, notez que, en R, un scalaire n’est rien d’autre qu’un vecteur de longueur 1. Ainsi, les deux écritures x <- 1
et x <- c(1)
sont équivalentes. De même x <- "Benjamin"
et x <- c("Benjamin")
sont équivalentes.
Pour mieux visualiser à quoi correspond les valeurs stockées dans un vecteur, on peut attribuer des noms aux différents éléments/composantes. Voici une illustration.
age height zipcode
22.00 1.84 1348.00
Pour un vecteur nommé, l’affichage de la fonction str()
est un peu différent.
Named num [1:3] 22 1.84 1348
- attr(*, "names")= chr [1:3] "age" "height" "zipcode"
On peut aussi nommer les éléments d’un vecteur au moment de sa création, comme ceci.
Finalement, sachez qu’il existe d’autres fonctions pour cerner les caractéristiques d’un objet en R comme par exemple les fonctions typeof()
et attributes()
.
[1] "double"
NULL
3.3 R est un langage vectoriel
R peut effectuer les opérations mathématiques classiques directement sur les vecteurs. Les opérations entre vecteurs se font membre à membre.
taille + c(1, 2, 3, 4, 5, 6, 7, 8, 9, 40)
taille^2
log(taille)
poids <- c(86, 74, 83, 50, 78, 66, 66, 51, 50, 55) # mesures en Kg
imc <- poids / (taille / 100)^2 # indice de masse corporelle (Kg/m^2)
imc
[1] 168 194 176 178 177 173 178 193 172 210
[1] 27889 36864 29929 30276 29584 27889 29241 34225 26569 28900
[1] 5.12 5.26 5.15 5.16 5.15 5.12 5.14 5.22 5.09 5.14
[1] 30.8 20.1 27.7 16.5 26.4 23.7 22.6 14.9 18.8 19.0
Si les vecteurs intervenant dans une opération ne sont pas de mêmes longueurs, la règle de recyclage s’applique. R automatiquement recycle l’objet le plus court assez de fois pour arriver à un objet de longueur égale à l’objet le plus long. Voici deux exemples.
[1] 187 212 193 194 192 187 191 205 183 190
[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 Warning est donné :
Warning in taille + 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
Cette sortie est la même que celle qu’on obtiendrait si on tape taille + c(0, 20, 1, 0, 20, 1, 0, 20, 1, 0)
.
3.4 Combiner des vecteurs
Imaginons que nous avons interrogé 10 autres personnes et récolté leurs tailles. Dans ce cas, il est naturel de vouloir combiner les deux échantillons dans un seul et même vecteur. Cette opération peut se faire aussi à l’aide de la fonction c()
.
taille1 <- taille
taille2 <- c(126, 177, 159, 143, 161, 180, 169, 159, 185, 160)
Taille <- c(taille1, taille2)
Taille
[1] 167 192 173 174 172 167 171 185 163 170 126 177 159 143 161 180 169 159 185
[20] 160
La même opération peut être effectuée comme suite.
Note
R distingue les majuscules et les minuscules. Ainsi, taille
, Taille
et taiLle
sont trois objets différents.
Conversion de types
Rappelons-nous que tous les éléments d’un vecteur doivent être du même type. Mais que se passe-t-il si nous combinons des objets de type différent ? Examinons les exemples suivants.
[1] 112 1 0
[1] "112" "Ben"
[1] "Ben" "TRUE" "FALSE"
On voit que R convertit automatiquement les éléments d’un vecteur pour qu’ils soient tous de mêmes types. Pour cela, il utilise la règle (symbolique) suivante.
\[
logique -> numérique -> caractère
\]
càd. R transforme un objet logique en un numérique (FALSE
devient 0
et TRUE
devient 1
) et un numérique en un caractère (1
devient "1"
, par exemple). Les caractères l’emportent toujours sur le reste.
Aussi, lorsqu’il s’agit d’effectuer des opérations mathématiques, R transforme automatiquement un objet logique en numérique.
[1] 0 1 3 4
[1] 1.00 1.00 2.72 2.72
Il existe des fonctions, de type as.*()
, pour réaliser des conversions de façon explicite. Voici un exemple
[1] "0" "1" "2" "3" "4"
Warning: NAs introduced by coercion
[1] 0 1 2 3 4 NA
Comme vous pourrez le constater ci-dessus, R retourne un NA
(Not Available), pour indiquer une valeur manquante.
Les NA
sont typiquement utilisés pour signaler une information non-disponible.
Par exemple, imaginez que la deuxième personne interrogée lors de notre enquête refuse de communiquer sa taille. Nous pouvons enregistrer cette information dans R comme ceci.
[1] 167 NA 173 174 172 167 171 185 163 170
Remarquez que NA
n’est pas la même chose que NaN
qui, pour rappelle, représente le résultat d’une opération numérique non défini (par exemple 0/0).
3.5 Opérateurs logiques et opérateurs de comparaison
Pour agir sur les vecteurs, R propose, en plus des opérateurs arithmétiques classiques (+
, -
, *
, …), deux autres types d’opérateurs : les opérateurs logiques qui s’appliquent sur les vecteurs logiques et les opérateurs de comparaison qui s’appliquent sur tout type d’objets.
Opérateurs logiques
Pour agir sur les vecteurs logiques, R propose un certain nombre d’opérateurs dont voici les plus utilisés en pratique.
Opérateur logique | Signification |
---|---|
& | et |
| | ou |
! | négation |
Voici un exemple.
[1] FALSE TRUE FALSE
[1] FALSE TRUE TRUE
[1] TRUE FALSE TRUE
Opérateurs de comparaison
Comme leur nom l’indique, ces opérateurs sont utiles pour comparer deux vecteurs.
Opérateur de comparaison | Signification |
---|---|
== | égal à |
!= | différent de |
> | strictement supérieur à |
< | strictement inférieur à |
>= | supérieur ou égal à |
<= | inférieur ou égal à |
Voici deux exemples.
[1] TRUE TRUE FALSE TRUE
[1] TRUE FALSE FALSE TRUE
[1] FALSE TRUE TRUE FALSE
[1] FALSE TRUE FALSE FALSE
[1] FALSE TRUE TRUE
On peut évidemment combiner les deux opérateurs (logiques et de comparaison) dans la même expression.
x <- c(1, 3, -1, 0)
y <- c(1, 0, 3, 0)
(x >= 0) & (x < 3) # trouves les éléments de x dans [0,3)
(x == y) | (x > y) # équivalent à écrire x >= y
[1] TRUE FALSE FALSE TRUE
[1] TRUE TRUE FALSE TRUE
Astuce: Comparer les nombres
Lors de test d’égalité entre des nombres, il arrive que R affiche FALSE
alors qu’il s’agit bel et bien de nombres identiques !
[1] FALSE
La raison est que, en system binaire (utilisé par R), les deux côtés de l’opérateur ==
ont une écriture différente.
[1] 0.30000000000000004441
[1] 0.2999999999999999889
Pour éviter ce type d’erreur, il est conseillé d’arrondir les nombres avant de les comparer
[1] TRUE
ou d’utiliser la fonction all.equal()
.
[1] TRUE
3.6 Accéder aux éléments d’un vecteur
Le but recherché ici est de pouvoir accéder, remplacer, modifier ou encore supprimer certains éléments d’un vecteur. Pour cela on utilise ce qu’on appelle l’indexation (ou sélection). Une indexation peut être numérique (appelé aussi indexation par position), par nom, ou logiques. Dans les trois cas, on utilisera les crochets [ ]
pour indiquer le ou les éléments à choisir ou à exclure.
Indexation numérique
Il s’agit de faire suivre le nom du vecteur de crochets contenant la position/numéro de(s) élément(s) (in)désiré(s). Voici quelques exemples
taille <- c(167, 192, 173, 174, 172, 167, 171, 185, 163, 170)
taille[1] # extraire le premier élément
taille[10] # dernier élément
taille[c(1, 5)] # premier et cinquième
taille[-c(1, 5)] # tous sauf premier et cinquième
[1] 167
[1] 170
[1] 167 172
[1] 192 173 174 167 171 185 163 170
La composition d’un vecteur n’est pas altérée lors de l’indexation, mais on peut se servir de cette dernière pour introduire des modifications dans le vecteur. Voici un exemple.
taille <- c(167, 192, 173, 174, 172, 167, 171, 185, 163, 170)
taille[1] <- 175 # modifier le 1er élément
taille[c(3, 10)] <- c(168, 170) # modifier le 3e et 10e élément
taille[11] <- 176 # ajouter un nouveau élément et le placer 11e
taille <- c(taille, 177) # ajouter un nouveau élément à la fin
taille <- taille[-2] # supprimer le 2e élément
taille
[1] 175 168 174 172 167 171 185 163 170 176 177
Parfois, il est utile de créer un vecteur vide et de la remplir par la suite (au fur et à mesure qu’on obtient des informations, par exemple).
[1] 2 NA 22
Indexation par nom
Dans le cas d’un vecteur nommé, on peut aussi utiliser les noms pour extraire ou modifier certains éléments.
zipcode age
1348 22
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.
Par exemple, supposons que l’on souhaite savoir le nom des fumeurs dans notre échantillon.
nom <- c("Benjamin", "Hugo", "Emma", "Alex", "Tom", "Axel", "Alice", "Martin", "Robin", "Enzo")
fum <- c(FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE)
nom[fum]
[1] "Emma" "Axel" "Enzo"
Comme vous pouvez le voir, nous n’obtenons que les éléments 3, 6, et 10 de nom
, car seuls ces derniers contiennent un TRUE
dans le vecteur logique fum
. Les deux vecteurs (à indexer (ici nom
) et le vecteur logique (ici fum
)) doivent être de même longueur, sinon le vecteur logique sera recyclé.
[1] "Benjamin" "Emma" "Alex" "Axel" "Alice" "Robin" "Enzo"
Voici d’autres exemples où l’indexation logique s’avère très utile.
nom <- c("Benjamin", "Hugo", "Emma", "Alex", "Tom", "Axel", "Alice", "Martin", "Robin", "Enzo")
taille <- c(167, 192, 173, 174, 172, 167, 171, 185, 163, 170)
nom[taille == 167] # noms des personnes dont la taille est de 167 cm.
nom[taille >= 172 & taille < 180] # noms des personnes dont la taille est dans [172,180).
nom[taille >= 172 & !fum] # taille >= 172 et non fumeur
[1] "Benjamin" "Axel"
[1] "Emma" "Alex" "Tom"
[1] "Hugo" "Alex" "Tom" "Martin"
3.7 Quelques fonctions usuelles
Nous allons lister ici une série de fonctions/exmples très fréquemment utilisé en pratique pour créer ou manipuler les vecteurs.
Créer des séquences régulières
Il y a plusieurs façons pour créer des séries numériques en R. Voici un aperçu.
1:10 # 1 à 10, par pas de 1
seq(1, 10) # 1 à 10, par pas de 1
seq(1, 10, by = 2.25) # 1 à 10, par pas de 2.25
seq(1, 10, length = 5) # 5 valeurs équidistantes de 1 à 10
rep(1:3, times = 3) # répéter (1,2,3) trois fois
rep(1:3, times = c(3, 2, 4)) # répéter 1 trois fois, 2 deux fois, et 3 quatre fois
[1] 1 2 3 4 5 6 7 8 9 10
[1] 1 2 3 4 5 6 7 8 9 10
[1] 1.00 3.25 5.50 7.75 10.00
[1] 1.00 3.25 5.50 7.75 10.00
[1] 1 2 3 1 2 3 1 2 3
[1] 1 1 1 2 2 3 3 3 3
Réarranger les éléments d’un vecteur
taille <- c(167, 192, 173, 174, 172, 167, 171, 185, 163, 170)
rev(taille) # inverser les éléments du vecteur
sort(taille) # ranger par ordre croissant
sort(taille, dec = TRUE) # ranger par ordre décroissant
order(taille) # indices pour ranger le vecteur par ordre croissant
[1] 170 163 185 171 167 172 174 173 192 167
[1] 163 167 167 170 171 172 173 174 185 192
[1] 192 185 174 173 172 171 170 167 167 163
[1] 9 1 6 10 7 5 3 4 8 2
Sommaires et statistiques descriptives
taille <- c(167, 192, 173, 174, 172, 167, 171, 185, 163, 170)
sum(taille) # somme des éléments
prod(taille) # produit des éléments
mean(taille) # moyenne (empirique)
max(taille) # maximum
min(taille) # minimum
range(taille) # min et max
median(taille) # médiane (empirique)
[1] 1734
[1] 2.43e+22
[1] 173
[1] 192
[1] 163
[1] 163 192
[1] 172
Toutes ces fonctions (et d’autres encore) acceptent l’argument na.rm
qui permet d’ignorer les valeurs manquantes dans le calcul. Pour voir comment cela marche, considérant l’exemple suivant.
[1] NA
[1] 1542
Parmi les fonctions statistiques les plus utiles, on trouve (1) la fonction générique summary()
qui résume les données sous forme de six chiffres clés (minimum, maximum, moyenne et quartiles), (2) la fonction table()
qui permet de compter le nombre d’occurrences de chaque élément (unique) d’un vecteur donné.
summary(taille) # statistiques descriptives
table(c("A", "B", "E", "E", "A", "A", "A", "B")) # comptage
Min. 1st Qu. Median Mean 3rd Qu. Max.
163 168 172 173 174 192
A B E
4 2 2
Recherche d’éléments dans un vecteur
# Positions des TRUE dans un vecteur logique
which(taille >= 180)
# Appartenance d'une ou plusieurs valeurs à un vecteur
1:10 %in% c(1, 3, 5, 9)
# Extraire les éléments uniques d'un vecteur
unique(c(5, 2, 1, 4, 6, 9, 8, 5, 7, 9))
[1] 2 8
[1] TRUE FALSE TRUE FALSE TRUE FALSE FALSE FALSE TRUE FALSE
[1] 5 2 1 4 6 9 8 7
Arrondi
x <- c(-3.6800000, -0.6666667, 3.1415927, 0.3333333, 1.2221201, 3.255166)
# Arrondi à un nombre défini de décimales (par défaut 0)
round(x, 4)
# Plus grand entier inférieur ou égal à l'argument
floor(x)
# Plus petit entier supérieur ou égal à l'argument
ceiling(x)
[1] -3.6800 -0.6667 3.1416 0.3333 1.2221 3.2552
[1] -4 -1 3 0 1 3
[1] -3 0 4 1 2 4
Concaténer des chaines de caractères
La fonction paste()
est utile dans une situation où on souhaite
« coller » des chaînes de caractères ensemble. Voici un exmple.
[1] "coucou comment vas-tu? j'espère que tout va bien."
[1] "coucou, comment vas-tu?, j'espère que tout va bien."
[1] "coucou1" "coucou2" "coucou3" "coucou4" "coucou5"