3  Vecteurs

Les vecteurs sont, sans conteste, la structure de données fondamentale et la plus simple de R. Le terme structure de données fait référence à la manière dont un objet est organisé et stocké en mémoire par R. C’est cette organisation qui détermine la manière dont R interprète les données et, par conséquent, les opérations statistiques ou mathématiques qui peuvent y être appliquées.

Techniquement, un vecteur est défini par son homogénéité : il stocke une liste ordonnée d’éléments qui doivent être tous du même type (mode), qu’il soit numérique, caractère ou logique. Tout objet respectant cette contrainte d’homogénéité est qualifié d’objet atomique.

En plus du vecteur, R met à disposition quatre autres structures de données majeures : Facteur, Matrice, Liste, et Data Frame. Ces deux derniers sont des structures composées ou récursives, car elles permettent l’hétérogénéité des types. Chacune de ces structures sera détaillée séparément dans les chapitres suivants.

3.1 Les trois types de vecteurs

R prend en charge plusieurs types atomiques. Parmi eux, les trois principaux sont :

  • Numérique (numeric) : Pour les nombres réels ou décimaux (mode par défaut pour les nombres).
  • Caractère (character) : Pour les données textuelles (chaînes de caractères).
  • Logique (logical) : Pour les valeurs booléennes (TRUE ou FALSE).

Numeric

Un vecteur numérique est la structure le plus couramment utilisé en R, car il permet de représenter des valeurs quantitatives (ou nombres).

Par exemple, 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ètres). On peut stocker cette série de mesures dans un seul objet à l’aide de la fonction c(), qui est utilisée pour combiner (ou concaténer) ses arguments en un unique vecteur.

taille <- c(167, 192, 173, 174, 172, 167, 171, 185, 163, 170) # mesures en cm
taille
 [1] 167 192 173 174 172 167 171 185 163 170

En réalité, R distingue formellement deux types de numériques :

  1. Les nombres réels ou décimaux : techniquement appelés doubles (double ou dbl). Ces valeurs sont stockées en virgule flottante.
  2. Les nombres entiers : désignés par integer (int).

Pour un utilisateur débutant, cette distinction n’a généralement pas beaucoup d’impact : Par défaut, R stocke toute valeur numérique comme un double. Le mode integer est cependant parfois privilégié pour des raisons d’efficacité de stockage et pour accélérer les calculs.

Note

Pour forcer la conversion d’un vecteur en mode integer, on peut utiliser la fonction as.integer(). Exemple: taille <- as.integer(taille).

Character

En R, le type character est utilisé pour stocker des données textuelles, càd des chaînes de caractères comme des mots, des phrases ou des symboles.

Imaginons que nous ayons aussi relevé le nom de chaque personne. Voici comment stocker cette information en utilisant la fonction c() :

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"    

Il est impératif que les chaînes de caractères soient délimitées par des guillemets, qu’ils soient doubles (") ou simples ('). Les deux notations sont acceptées par R et peuvent être employées de manière interchangeable au sein d’un même vecteur, comme illustré ci-dessus. Ce délimiteur signale à R que le contenu est à traiter comme du texte littéral.

Logical

Le mode logique (logical) est utilisé pour stocker des valeurs booléennes, représentant des conditions binaires telles que vrai ou faux, oui ou non, pressent ou absent, etc. En R, TRUE et FALSE sont les constantes logiques utilisées pour représenter les deux états possibles d’un objet logique.

Par exemple, définissons le statut de fumeur (Oui/Non) pour chaque individu. Puisqu’il s’agit d’une quantité binaire, on peut utiliser un vecteur logique pour stocker cette information :   

fum <- c(FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE)
fum
 [1] FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE

Bien qu’il soit techniquement possible d’utiliser les abréviations T et F en lieu et place des constantes logiques, il est fortement recommandé d’utiliser la forme complète (TRUE et FALSE). Cette bonne pratique permet d’éviter les confusions, notamment le risque de masquage des constantes logiques. En effet, si l’utilisateur définit accidentellement des objets nommés T ou F dans son environnement, cela pourrait altérer le comportement du code.

3.2 Mieux connaître un vecteur

Vecteurs nommés

Pour mieux contextualiser les valeurs stockées dans un vecteur, il est possible d’attribuer des noms à ses différents éléments/composantes. On obtient ainsi un vecteur nommé.

Voici un exemple où les noms sont assignés après la création du vecteur :

person1 <- c(22, 1.84, 1348)
names(person1) <- c("age", "height", "zipcode")
person1
    age  height zipcode 
  22.00    1.84 1348.00 

Il est également possible de nommer les éléments d’un vecteur au moment de sa création. Pour cela, il suffit d’associer un nom à chaque valeur directement dans l’appel à c(), comme dans l’exemple ci‑dessous :

person1 <- c(age = 22, height = 1.84, zipcode = 1348)

str() : structure d’un objet

Pour inspecter la structure interne d’un objet en R, la fonction str() (structure) est essentielle à connaître. Elle s’applique à n’importe quel objet R (pas uniquement les vecteurs) et fournit un résumé concis de sa nature, de ses dimensions et d’un aperçu de son contenu.

str(taille)
str(nom)
str(fum)
 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 la nature de chaque objet (modes : num pour numérique, chr pour caractère, logi pour logique), ainsi que sa longueur ou sa taille ([1:10]), et un aperçu de ses premières valeurs stockées.

L’affichage de la fonction str() s’adapte aux caractéristiques et aux attributs de l’objet à examiner. Exemple :

str(person1)
 Named num [1:3] 22 1.84 1348
 - attr(*, "names")= chr [1:3] "age" "height" "zipcode"

Cette sortie indique que person1 est un vecteur numérique nommé de longueur 3. La deuxième ligne précise que ce vecteur possède un attribut names, qui est lui-même un vecteur de caractères de longueur 3.

En plus de str(), R propose plusieurs autres fonctions utiles pour explorer et comprendre la nature d’un objet. Les principales fonctions sont illustrées à l’aide de l’exemple suivant :

class(person1)       # Indique la nature de l'objet ("data.frame", "factor", etc)
typeof(person1)      # Montre comment l’objet est stocké en mémoire (character, double, etc)
attributes(person1)  # Affiche tous les attributs associés à l’objet (noms, dimensions, etc.)
length(person1)      # Donne le nombre de composants ou d’éléments dans l’objet
names(person1)       # Affiche les noms des composants
[1] "numeric"
[1] "double"
$names
[1] "age"     "height"  "zipcode"

[1] 3
[1] "age"     "height"  "zipcode"

Il est intéressant de s’arrêter sur la fonction names(), qui illustre bien la propriété bidirectionnelle de certaines fonctions en R. En effet, lorsqu’on écrit names(<objet>), la fonction est utilisée pour consulter (lire) les noms associés. Mais lorsqu’on utilise la syntaxe d’assignation, names(<objet>) <- <valeur>, la même fonction est utilisée pour attribuer ou modifier (écrire) ces noms. D’autres fonctions possèdent cette même propriété de lecture-écriture pour la gestion des attributs, notamment length(), dim(), et levels(), que nous verrons plus loin.

Les dates

Il arrive souvent, dans l’analyse de données, que l’on doive manipuler des informations temporelles — comme des données longitudinales ou des séries chronologiques, par exemple. Pour cela, R propose un type d’objet dédié, sobrement nommé Date, qui permet de représenter et de traiter les dates de manière fiable et cohérente.

La fonction as.Date() permet de convertir des chaînes de caractères en objets de classe Date. Exemple :

dates_naissance <- c("1995-05-12", "2001-11-25", "1988-08-01", "2005-01-15") |> as.Date()
str(dates_naissance)
 Date[1:4], format: "1995-05-12" "2001-11-25" "1988-08-01" "2005-01-15"

Un objet de type Date, tel que défini par la fonction as.Date(), permet d’interpréter correctement une chaîne de caractères comme un moment calendaire. Cela rend possible des opérations temporelles précises, telles que : le calcul de la différence entre deux dates, la comparaison chronologique, le tri par ordre chronologique, l’extraction de composantes comme l’année, le mois ou le jour, etc. Exemple :

min(dates_naissance) |> months()  # Extraire le mois de la plus ancienne date
Sys.Date() - min(dates_naissance) # Calculer la durée (en jours) écoulée depuis la plus ancienne date
[1] "August"
Time difference of 13645 days

Techniquement, un vecteur Date est stocké en interne comme un vecteur d’entiers représentant le nombre de jours écoulés depuis le 1er janvier 1970. En effet,

typeof(dates_naissance)
as.Date("1970-01-01") |> as.numeric()
as.Date("1970-01-01") + 365
[1] "double"
[1] 0
[1] "1971-01-01"

3.3 R : Un langage orienté vecteur

En R, la plupart des opérations sont conçues pour s’appliquer directement à des vecteurs dans leur ensemble, plutôt que de manière élément par élément. Cette approche, appelée vectorisation, permet d’effectuer des calculs plus rapidement et plus efficacement, en évitant le recours à des boucles explicites. Les fonctions vectorisées exploitent des optimisations internes, ce qui améliore considérablement les performances.

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.117994 5.257495 5.153292 5.159055 5.147494 5.117994 5.141664 5.220356
 [9] 5.093750 5.135798
 [1] 30.83653 20.07378 27.73230 16.51473 26.36560 23.66524 22.57105 14.90139
 [9] 18.81892 19.03114

Règle de recyclage

Si les vecteurs impliqués dans une opération n’ont pas la même longueur, la règle de recyclage s’applique. Cela signifie que les éléments du vecteur le plus court sont répétés (ou “recyclés”) pour correspondre à la longueur du vecteur le plus long. Cette règle permet à R d’effectuer des opérations vectorisées sans générer d’erreur, même lorsque les longueurs diffèrent. Voici deux exemples.

1taille + 20
2taille + c(0, 20)
1
équivalent à : taille + c(20, 20, 20, 20, 20, 20, 20, 20, 20, 20).
2
équivalent à : taille + c(0, 20, 0, 20, 0, 20, 0, 20, 0, 20)
 [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é :

taille + c(0, 20, 1)
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

Ce résultat est le même que celui qu’on obtiendrait en tapant taille + c(0, 20, 1, 0, 20, 1, 0, 20, 1, 0).

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.

Taille <- c(taille, 126, 177, 159, 143, 161, 180, 169, 159, 185, 160)
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.

c(112, TRUE, FALSE)
c(112, "Ben")
c("Ben", TRUE, FALSE)
[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 \: \rightarrow \: numérique \: \rightarrow \: 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, par example, R transforme automatiquement un objet logique en numérique.

c(FALSE, FALSE, TRUE, TRUE) + c(0, 1, 2, 3)
exp(c(FALSE, FALSE, TRUE, TRUE))
[1] 0 1 3 4
[1] 1.000000 1.000000 2.718282 2.718282

Il existe des fonctions, de type as.*(), pour réaliser des conversions de façon explicite. Voici un exemple

as.character(c(0, 1, 2, 3, 4))
as.logical(c(0, 1, 2, 3, 4))
as.numeric(c(TRUE, FALSE))
as.numeric(c("0", "1", "2", "3", "4", "a"))
[1] "0" "1" "2" "3" "4"
[1] FALSE  TRUE  TRUE  TRUE  TRUE
[1] 1 0
[1]  0  1  2  3  4 NA

NA: Valeur manquante

Dans la sortie ci-dessus, on observe la présence d’un NA (Not Available), qui signale une valeur manquante. Cela se produit car R tente de convertir chaque élément du vecteur en une valeur numérique. Mais puisque il ne sait pas comment convertir “a” en un nombre, il renvoie NA pour signaler l’échec de la conversion. Ce comportement est accompagné d’un Warning : “NAs introduced by coercion”.

Les NA sont typiquement utilisés pour signaler une information non-disponible. 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.

tailes <- c(167, NA, 173, 174, 172, 167, 171, 185, 163, 170)
tailes
 [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 rappel, représente le résultat d’une opération numérique indéfinie (par exemple 0/0). Un NaN est considéré par R comme un cas particulier de NA, mais l’inverse n’est pas vrai. Le code suivant illustre cette distinction :

c(1, 2, NaN, NA, 4) |> is.na()
c(1, 2, NaN, NA, 4) |> is.nan()
[1] FALSE FALSE  TRUE  TRUE FALSE
[1] FALSE FALSE  TRUE FALSE FALSE

3.4 Opérateurs logiques et opérateurs de comparaison

En plus des opérateurs arithmétiques classiques (+, -, *, etc.), R propose deux autres familles d’opérateurs essentiels pour manipuler les vecteurs :

  • Les opérateurs logiques, qui s’appliquent aux vecteurs de type logique (TRUE/FALSE).
  • Les opérateurs de comparaison, qui permettent de comparer des éléments entre eux, quel que soit leur type.

Opérateurs logiques

Ces opérateurs permettent d’agir sur des valeurs logiques, càd des vecteurs contenant TRUE et/ou FALSE. Les plus utilisés en pratique sont :

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

Exemple :

x <- c(FALSE, TRUE, FALSE)
y <- c(FALSE, TRUE, TRUE)

x & y
x | y
!x
[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 à

Exemple 1

x <- c(1, 3, -1, 0)
y <- c(1, 0, 3, 0)

x >= 0
x == y
x != y
x > y
[1]  TRUE  TRUE FALSE  TRUE
[1]  TRUE FALSE FALSE  TRUE
[1] FALSE  TRUE  TRUE FALSE
[1] FALSE  TRUE FALSE FALSE

Exemple 2

z <- c("D", "B", "C")
w <- c("A", "B", "E")

z <= w
[1] FALSE  TRUE  TRUE

On peut évidemment combiner les deux opérateurs (logiques et de comparaison) dans la même expression. Exemple

x <- c(1, 3, -1, 0)
y <- c(1, 0, 3, 0)

(x >= 0) & (x < 3) # Éléments de x dans [0, 3[
(x == y) | (x > y) # Éléments de x >= à ceux de y (équivalent à x >= y)
[1]  TRUE FALSE FALSE  TRUE
[1]  TRUE  TRUE FALSE  TRUE

3.5 Accéder aux éléments d’un vecteur

L’objectif ici est d’apprendre à accéder, modifier, ou supprimer certains éléments d’un vecteur. Pour cela, on utilise ce qu’on appelle l’indexation (ou sélection). En R, l’indexation peut être : (i) Numérique (par position); (ii) Par nom; ou (ii) Logique (par condition)

Dans tous les cas, on utilise les crochets [ ] pour indiquer les éléments concernés.

Indexation numérique

Il s’agit de faire suivre le nom du vecteur de crochets contenant la position/numéro des éléments (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]         # Extraire le dernier élément
taille[c(5, 1)]    # Extraire le 5e et le 1er élément
taille[-c(1, 5)]   # Exclure le 1er et le 5e élément
[1] 167
[1] 170
[1] 172 167
[1] 192 173 174 167 171 185 163 170

L’indexation, comme la plupart des opérations et fonctions courantes en R, ne modifie pas le vecteur original, sauf si elle est utilisée dans une affectation. Exemple :

taille[1] <- 1                 # Modifier le 1er élément
taille[c(3, 10)] <- c(3, 10)   # Modifier les 3e et 10e éléments
taille[11] <- 11               # Ajouter un 11e élément
taille <- taille[-2]           # Supprimer le 2e élément

taille
 [1]   1   3 174 172 167 171 185 163  10  11

Notez qu’il est aussi possible de créer un vecteur vide et de le remplir progressivement (au fur et à mesure qu’on accumule de l’information, par exemple) :

x <- c()
x[1] <- 2
x[5] <- 22
x
[1]  2 NA NA NA 22

Indexation par nom

Si le vecteur possède des noms, on peut accéder aux éléments via ces noms. Exemple :

person1 <- c(age = 22, height = 1.84, zipcode = 1348)

person1["age"]
person1[c("zipcode", "age")]
age 
 22 
zipcode     age 
   1348      22 

Indexation logique

L’indexation logique permet de sélectionner les éléments qui répondent à une condition logique. Exemple :

nom <- c("Benjamin", "Hugo", "Emma", "Alex", "Tom", "Axel", "Alice", "Martin", "Robin", "Enzo")
fum <- c(FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE)

1nom[fum]
1
Cela signifie : extraire les éléments de nom pour lesquels fum est TRUE. Càd les noms des fumeurs.
[1] "Emma" "Axel" "Enzo"

La fonction which() permet d’explicitement obtenir les positions (les indices numériques) des éléments TRUE dans un vecteur logique. Cela peut être utile si l’on veut ensuite les utiliser dans d’autres opérations.

which(fum)        # Renvoie les indices des fumeurs (fum = TRUE)
nom[which(fum)]   # Équivalent à nom[fum]
[1]  3  6 10
[1] "Emma" "Axel" "Enzo"

Attention au recyclage : Pour que l’indexation logique fonctionne correctement, les deux vecteurs impliqués doivent avoir la même longueur. Sinon, R applique un recyclage implicite (sans aucun Warning). Cela peut entraîner des résultats inattendus ou erronés.

1nom[c(TRUE, FALSE, TRUE)]
1
Équivalent à nom[c(TRUE,FALSE,TRUE,TRUE,FALSE,TRUE,TRUE,FALSE,TRUE,TRUE)].
[1] "Benjamin" "Emma"     "Alex"     "Axel"     "Alice"    "Robin"    "Enzo"    

Voici d’autres exemples d’indexation logique :

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 mesurant 167 cm
nom[taille >= 172 & taille < 180]   # Noms des personnes mesurant entre 172 et 180 cm
nom[taille >= 172 & !fum]           # Noms des non-fumeurs mesurant ≥ 172 cm
[1] "Benjamin" "Axel"    
[1] "Emma" "Alex" "Tom" 
[1] "Hugo"   "Alex"   "Tom"    "Martin"

L’indexation logique peut aussi se réaliser via la fonction subset(). La syntaxe générale est subset(<vecteur>, subset = <condition>) :

subset(nom, subset = taille == 167)
## ou
## nom |> subset(taille == 167)
[1] "Benjamin" "Axel"    

subset() est très pratique pour filtrer les lignes d’un data frame selon des conditions logiques. Nous verrons comment l’utiliser efficacement dans ce contexte un peu plus loin.

3.6 Quelques fonctions usuelles

Cette section présente une sélection de fonctions fréquemment utilisées en R pour créer, manipuler, analyser ou transformer des vecteurs.

Dans la suite du document, certaines sorties seront masquées afin d’alléger la présentation. Pour les afficher, cliquez sur le bouton “Output” situé juste en dessous du bloc de code.

Créer des séquences régulières

R propose plusieurs méthodes pour générer des suites numériques :

1:10                             # Séquence de 1 à 10, pas de 1
seq(1, 10)                       # Idem
seq(1, 10, by = 2.25)            # Séquence de 1 à 10, pas de 2.25
seq(1, 10, length = 5)           # 5 valeurs équidistantes entre 1 et 10
rep(1:3, times = 3)              # Répète (1, 2, 3) trois fois
rep(1:3, times = c(3, 2, 4))     # Répète 1 trois fois, 2 deux fois, 3 quatre fois
Output
 [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)                      # Inverse l’ordre des éléments
sort(taille)                     # Trie par ordre croissant
sort(taille, decreasing = TRUE)  # Trie par ordre décroissant
order(taille)                    # Renvoie les indices pour trier le vecteur
Output
 [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

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
max(taille)       # Maximum
min(taille)       # Minimum
range(taille)     # Intervalle (min et max)
median(taille)    # Médiane
Output
[1] 1734
[1] 24303136934026482286482
[1] 173.4
[1] 192
[1] 163
[1] 163 192
[1] 171.5

Les fonctions statistiques acceptent typiquement l’argument na.rm qui permet d’ignorer les valeurs manquantes dans le calcul. Pour voir comment cela marche, considérant l’exemple suivant.

tailes <- c(167, NA, 173, 174, 172, 167, 171, 185, 163, 170)

sum(tailes)
sum(tailes, na.rm = TRUE)
[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 d’un vecteur donné.

summary(taille)                                           # Statistiques descriptives
c("A", "B", "E", "E", "A", "A", "A", "B") |> table()      # Comptage
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  163.0   167.8   171.5   173.4   173.8   192.0 

A B E 
4 2 2 

Recherche d’éléments dans un vecteur

taille <- c(167, 192, 173, 174, 172, 167, 171, 185, 163, 170)

1which(taille >= 180)
2c(160, 192, 200, 163) %in% taille
3unique(c(5, 2, 1, 4, 6, 9, 8, 5, 7, 9))
1
Positions des TRUE dans un vecteur logique (déjà abordé; voir Section 3.5.3).
2
L’opérateur %in% permet de tester l’appartenance d’un ou plusieurs éléments à un ensemble. x %in% y signifie : quels sont les éléments de x qui se trouvent dans y. Le résultat est un vecteur logique de la même longueur que x.
3
Extraire les éléments uniques d’un vecteur.
[1] 2 8
[1] FALSE  TRUE FALSE  TRUE
[1] 5 2 1 4 6 9 8 7

Pour les vecteurs de type caractère, l’une des fonctions les plus utiles est grep(). Elle permet de rechercher un motif (un mot, une suite de lettres, un symbole) dans un vecteur. Par défaut, grep() renvoie les indices des éléments qui contiennent le motif recherché, mais l’argument value = TRUE permet d’obtenir directement les chaînes correspondantes.

nom <- c("Benjamin", "Hugo", "Emma", "Alex", "Tom", "Axel", "Alice", "Martin", "Robin", "Enzo")

grep("Al", nom)
grep("Al", nom, value = TRUE)
[1] 4 7
[1] "Alex"  "Alice"

La fonction grep() accepte également les expressions régulières, ce qui permet de rechercher non seulement des mots exacts, mais aussi des motifs plus généraux. Voici quelque exemples :

grep("^A", nom, value = TRUE)    # Eléments qui commencent par la lettre A
grep("[xz]", nom, value = TRUE)  # Eléments contenant un x ou un z
[1] "Alex"  "Axel"  "Alice"
[1] "Alex" "Axel" "Enzo"

Sans entrer dans les détails, sache que les expressions régulières offrent une grande flexibilité pour analyser ou filtrer du texte. Pour en savoir plus, vous pouvez consulter l’aide intégrée de R avec ?grep et ?regex.

Arrondir et comparer

Dans de nombreuses situations, il est utile de manipuler des nombres réels avec un certain niveau de précision, que ce soit pour les afficher ou les comparer. Pour cela, R met à disposition plusieurs fonctions utiles permettant d’arrondir, tronquer ou tester l’égalité entre valeurs numériques.

x <- c(-3.6800000, -0.6666667, 3.1415927, 0.3333333, 1.2221201, 3.255166)

round(x, digits = 4)   # Arrondi à 4 décimales (par défaut digits = 0)
floor(x)               # Partie entière inférieure
ceiling(x)             # Partie entière supérieure
[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

Il arrive qu’une comparaison entre deux nombres apparemment identiques retourne FALSE :

0.1 + 0.2 == 0.3
[1] FALSE

Il ne s’agit pas d’un bug de R, mais d’une limitation fondamentale liée à la manière dont les nombres réels sont représentés et stockés en informatique. Contrairement aux mathématiques pures, où les nombres peuvent avoir une précision infinie, les ordinateurs utilisent des approximations binaires qui introduisent de légers écarts. Pour le constater :

print(0.1 + 0.2, digits = 22)
print(0.3, digits = 22)
(0.1 + 0.2) - 0.3
[1] 0.3000000000000000444089
[1] 0.2999999999999999888978
[1] 0.00000000000000005551115

Solutions pour contourner ce problème :

  • Arrondir les nombres avant de les comparer

    round(0.1 + 0.2, 10) == 0.3
    [1] TRUE
  • Utiliser la fonction all.equal() qui permet de comparer deux objets en tenant compte des petites différences dues à la précision numérique.

    all.equal(0.1 + 0.2, 0.3)
    [1] TRUE

Concaténer des chaines de caractères

La fonction paste() est utile dans une situation où l’on souhaite combiner des chaînes de caractères ensemble. Voici quelques exemples.

a <- "coucou"
b <- "comment vas-tu?"
c <- "j'espère que tout va bien !"

paste(a, b, c)               # Séparateur par défaut : espace
paste(a, b, c, sep = ", ")   # Séparateur personnalisé
paste(a, b, c, sep = "")     # Collage sans espace (équivalent à paste0)
paste(a, 1:5, sep = "")      # Génère : "coucou1", "coucou2", ...
[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] "coucoucomment vas-tu?j'espère que tout va bien !"
[1] "coucou1" "coucou2" "coucou3" "coucou4" "coucou5"
Note

À la différence de cat(), qui concatène et affiche immédiatement le résultat dans la console, paste() renvoie une chaîne de caractères que l’on peut ensuite stocker dans un objet, manipuler ou réutiliser dans d’autres opérations.

all() et any()

Ces fonctions servent à tester, dans un vecteur logique, si tous les éléments sont TRUE (all()), ou si au moins un élément est TRUE (any()).

Elles sont souvent utilisées pour tester des conditions sur des vecteurs. Exemple :

age <- c(23, 35, 42, 20, 51, 67, 45, 60, 18, 15, 38, 30, 85)

any(age == 15)
all(age >= 18)
[1] TRUE
[1] FALSE