6. Vecteurs
R manipule deux types de structures de données:
les structures de données de base
les structures de données composites
La structure de base la plus simple est le vecteur et nous allons étudier son fonctionnement dans ce chapitre.
Pour stocker des données hétérogènes et complexes, on a besoin de structures de données composites, plus évoluées. La data.frame
en fait partie. On étudiera son fonctionnement dans le chapitre Data frames.
6.1. Définition
Un vecteur est une entité consistant en une collection ordonnée d’éléments atomiques. Par élément atomique, on entend :
Atomic Types |
Data |
---|---|
numeric |
Numeric data (approximations of the real numbers) |
integer |
Integer data (whole numbers). integer is a subclass of numeric |
complex |
Complex numbers |
logical |
Boolean |
character |
Character data (strings) |
raw |
Binary data |
Dans le langage R, les vecteurs:
sont homogènes (ne stockent que des données de même type)
sont indexables (on peut récupérer un ou plusieurs éléments à partir de leur position)
peuvent avoir des éléments nommés
Pour construire un vecteur x
contenant 5 éléments (10.4, 5.6, 3.1, 6.4 et 21.7), on utilise la commande suivante:
> x <- c(10.4, 5.6, 3.1, 6.4, 21.7)
> x
[1] 10.4 5.6 3.1 6.4 21.7
C’est une instruction d’affectation pour laquelle on retrouve:
à gauche : le nom de la variable
à droite : la fonction
c()
prenant un nombre arbitraire d’arguments et retournant un vecteur dont les éléments sont obtenus par concaténation de ses arguments.
Notons que les vecteurs ont une structure « plate », indépendamment de l’instruction de construction:
> x <- c(10.4, c(5.6, 3.1, c(6.4, 21.7)))
> x
[1] 10.4 5.6 3.1 6.4 21.7
Avertissement
Les affectations peuvent également utiliser la fonction assign()
mais son utilisation n’est pas encouragée pour des raisons évidentes de simplicité d’écriture:
> assign("x", c(10.4, 5.6, 3.1, 6.4, 21.7))
L’opérateur <-
peut être vu comme un raccourci syntaxique et sera utilisé de façon préférentielle.
Considérons l’affectation suivante:
> y <- c(x, 0, x)
> y
[1] 10.4 5.6 3.1 6.4 21.7 0.0 10.4 5.6 3.1 6.4 21.7
Un vecteur y
est créé en concaténant les arguments de la fonction c()
dans l’ordre d’apparition.
Il est possible d’insérer une ou plusieurs valeurs dans un vecteur avec la fonction append()
:
> append(x,99)
[1] 10.4 5.6 3.1 6.4 21.7 99.0
> append(x,99,3) # third argument describe position where values will be inserted
[1] 10.4 5.6 3.1 99.0 6.4 21.7
> append(x,c(99,100),3) # multiple values insertion
[1] 10.4 5.6 3.1 99.0 100.0 6.4 21.7
6.2. Arithmétique des vecteurs
Voici quelques règles qui régissent le comportement des vecteurs:
lorsque des vecteurs sont utilisés dans une expression arithmétique, les opérations sont effectuées élément par élément
les vecteurs n’ont pas besoin d’avoir une longueur identique, un processus de recyclage de données permet de construire un vecteur résultat de taille la plus grande taille des vecteurs mis en jeu. En particulier une constante sera transformé en un vecteur par répétition de sa valeur.
Question
Essayer de prédire le résultat de v <- 2*x + y + 1
en répondant préalablement aux questions suivantes:
quelle est la longueur de
x
?quelle est la longueur de
y
?quelle est la longueur de
1
?quel est le vecteur le plus long ?
imaginer la règle de recyclage du vecteur le plus court
Utiliser la console R pour vérifier
En utilisant les vecteurs précédents, le résultat devrait être:
> v <- 2*x + y + 1
Warning message:
In 2 * x + y :
longer object length is not a multiple of shorter object length
> v
[1] 32.2 17.8 10.3 20.2 66.1 21.8 22.6 12.8 16.9 50.8 43.5
R construit un nouveau vecteur v
:
de longueur 11, la longueur de
y
le plus long vecteur mis en jeurecycle les valeurs de
x
jusqu’à obtenir un vecteur de longueur 11 : 10.4 5.6 3.1 6.4 21.7 (+) 10.4 5.6 3.1 6.4 21.7 (+) 10.4recycle la valeur
2
jusqu’à obtenir un vecteur de longueur 11 : 2 2 2 2 2 2 2 2 2 2 2recycle la valeur
1
jusqu’à obtenir un vecteur de longueur 11 : 1 1 1 1 1 1 1 1 1 1 1effectue l’arithmétique élément par élément
Question
Quel est le sens du warning affiché dans la console lors de la construction de v
?
Les opérateurs arithmétiques sont :
+
-
*
/
^
(exponentiation)
Les opérations mathématiques courantes:
log()
exp()
sin()
cos()
tan()
sqrt()
…
Les fonctions max()
et min()
retournent la plus grande et la plus petite valeur du vecteur passé en argument sous la forme d’un vecteur de taille 1
(il n’y a pas de scalaire en R):
> v
[1] 32.2 17.8 10.3 20.2 66.1 21.8 22.6 12.8 16.9 50.8 43.5
> max(v)
[1] 66.1
> min(v)
[1] 10.3
La fonction range()
utilise les fonctions min()
et max()
pour construire le résultat:
> range(v)
[1] 10.3 66.1
La fonction length()
retourne le nombre d’éléments:
> length(v)
[1] 11
La fonction sum()
fait ce qu’elle doit faire:
> sum(v)
[1] 315
et la fonction prod()
également:
> prod(v)
[1] 1.856438e+15
On a vu précédemment que la fonction summary()
produisait des statistiques de premier ordre. La moyenne est obtenue avec mean()
et la variance avec var()
:
> mean(v)
[1] 28.63636
> var(v)
[1] 312.4905
La fonction sort()
retourne une permutation du vecteur passé en argument, avec les éléments ordonnés dans le sens croissant:
> v
[1] 32.2 17.8 10.3 20.2 66.1 21.8 22.6 12.8 16.9 50.8 43.5
> sort(v)
[1] 10.3 12.8 16.9 17.8 20.2 21.8 22.6 32.2 43.5 50.8 66.1
Astuce
La plupart du temps le tri sera effectué sur une partie d’une data frame avec les fonctions du package dplyr
. Si le besoin de trier de simples vecteurs se fait sentir, la fonction sort()
dispose de plusieurs arguments explicités dans la documentation. Et d’autres fonctions sont également disponibles : order()
, sort.list()
, …
Les fonctions max()
et min()
fonctionnent également avec plusieurs arguments. Construisons 2 vecteurs constitués de valeurs aléatoires. On utilise pour celà la fonction sample()
> a <- sample(1:100, 10, replace=FALSE)
> a
[1] 3 33 11 80 68 58 15 50 4 99
> b <- sample(1:100, 20, replace=FALSE)
> b
[1] 99 88 91 28 63 100 13 95 4 32
Sans surprise
> min(a,b)
[1] 3
> max(a,b)
[1] 100
Les fonctions pmax()
(parallel max) and pmin()
(parallel min) retourne un vecteur de longueur la taille du plus long argument, constitué pour chaque position, de la valeur max ou min prise élément par élément.
Question
Essayer de prédire le résultat retourné par pmax()
et pmin()
lorsque ces fonctions sont appliquées aux vecteurs a
et b
. Utiliser la console de R pour vérifier…
6.3. Génération de séquences
La plupart du temps on travaille avec des jeux de données importés mais il est parfois nécessaire de compléter ces données en produisant des vecteurs de taille arbitraire. R dispose de plusieurs mécanismes pour « fabriquer » des données.
6.3.1. L’opérateur :
On a déjà rencontré cet opérateur en début de chapitre.
1:10
est l’équivalent de c(1, 2, ..., 10)
:
> 1:10
[1] 1 2 3 4 5 6 7 8 9 10
L’opérateur :
a une priorité plus grande que les opérateurs arithmétiques:
> 2*1:10
[1] 2 4 6 8 10 12 14 16 18 20
Question
Essayer de prédire le résultat des deux séquences ci dessous:
> n <- 10
> 1:n-1
> 1:(n-1)
Vérifier dans la console…
La construction 10:1
est utilisé pour générer une séquence dans l’ordre décroissant:
> 10:1
[1] 10 9 8 7 6 5 4 3 2 1
6.3.2. La fonction seq()
La fonction seq()
peut également être utilisée. Elle comporte 5 arguments, dont certains sont optionnels.
Lorsqu’on l’utilise avec seulement deux arguments, elle se comporte comme l’opérateur :
:
> seq(2,10)
[1] 2 3 4 5 6 7 8 9 10
On peut également passer les informations avec des arguments nommés:
> seq(1,10)
[1] 1 2 3 4 5 6 7 8 9 10
> seq(from=1, to=10)
[1] 1 2 3 4 5 6 7 8 9 10
> seq(to=10, from=1)
[1] 1 2 3 4 5 6 7 8 9 10
Les arguments optionnels by=value
et length=value
permettent de spécifier le pas et la longueur de la séquence. Si aucun n’est fourni la valeur par défaut by=1
est utilisée:
> seq(-1, 1, by=.3)
[1] -1.0 -0.7 -0.4 -0.1 0.2 0.5 0.8
> seq(length=9, from=-5, by=.2)
[1] -5.0 -4.8 -4.6 -4.4 -4.2 -4.0 -3.8 -3.6 -3.4
Le cinquième argument along=vector
est utilisé pour construire une séquence de longueur la longueur du vecteur passé en argument:
> seq(3, along=c("a", "b", "c", "d", "e"))
[1] 3 4 5 6 7
6.3.3. La fonction rep()
La fonction rep()
est utilisé pour dupliquer des données.
Dans sa forme la plus simple:
> x <- c(10.4, 5.6, 3.1, 6.4, 21.7)
> rep(x, times=2)
[1] 10.4 5.6 3.1 6.4 21.7 10.4 5.6 3.1 6.4 21.7
Une autre façon de l’utiliser:
> rep(x, each=2)
[1] 10.4 10.4 5.6 5.6 3.1 3.1 6.4 6.4 21.7 21.7
6.4. Vecteurs logiques
On a beaucoup travaillé jusqu’à présent avec des grandeurs numériques mais R permet également de manipuler des vecteurs logiques. Les valeurs utilisées sont TRUE
, FALSE
, et NA
. Les deux premières sont souvent abrégées par T
et F
.
Avertissement
T
et F
sont de simples variables initialisées à TRUE
et FALSE
et peuvent être écrasées par l’utilisateur. La rigueur imposerait de toujours travailler avec TRUE
et FALSE
qui sont des variables réservées par le système.
Pour illustrer le fonctionnement des vecteurs logiques, utilisons le vecteur x
créé précédemment:
> x
[1] 10.4 5.6 3.1 6.4 21.7
Question
Essayer de prédire le résultat de l’expression x > 6
en inférant la longueur du vecteur résultat et en se souvenant que R travaille élément par élément.
Les opérateurs logiques sont:
<
<=
>
>=
==
(égalité exacte)!=
(inégalité)
Si c1
et c2
sont des expressions logiques:
c1 & c2
exprime le ET logiquec1 | c2
exprime le OU logique!c1
exprime la négation
Important
Si les vecteurs logiques sont impliqués dans des expressions arithmétiques, les valeurs logiques TRUE
et FALSE
sont forcées à 1
et 0
6.5. Valeurs manquantes
Comme au l’a vu dans le paragraphe Nombres spéciaux, il peut y avoir des éléments manquants dans un vecteur identifiés par le nombre spécial NA
. En général, toute opération impliquant un NA
retourne un NA
.
La fonction is.na()
retourne un vecteur logique de même taille que celui passé en paramètre et comportant la valeur TRUE
si l’élément correspondant est NA
:
> z <- c(1:3,NA)
> z
[1] 1 2 3 NA
> is.na(z)
[1] FALSE FALSE FALSE TRUE
La fonction is.na()
retourne TRUE
pour les valeurs NA
et NaN
.
La fonction is.nan()
retourne TRUE
pour les seules valeurs NaN
:
> z <- append(z, NaN)
> z
[1] 1 2 3 NA NaN
> is.na(z)
[1] FALSE FALSE FALSE TRUE TRUE
> is.nan(z)
[1] FALSE FALSE FALSE FALSE TRUE
Important
Lorsqu’on travaille avec des jeux de données réélles, il est de première importance d’identifier les observations complètes (ne comportant aucun NA
) et les observations incomplètes (comportant au moins un NA
).
6.6. Vecteurs de caractères
Les chaines de caractères se définissent avec la double "
ou simple apostrophe '
. Un vecteur de chaines de caractères est une séquence ordonnée de chaines de caractères.
A titre d’exemple, la fonction names()
appliquée à la data.frame
contenant les informations sur les véhicules utilisée dans le chapitre Un aperçu du fonctionnement de R retourne un tel vecteur:
> names(veh)
[1] "lib_mrq" "lib_mod_doss" "lib_mod"
[4] "dscom" "cnit" "tvv"
[7] "cod_cbr" "hybride" "puiss_admin_98"
[10] "puiss_max" "typ_boite" "nb_rapp"
[13] "conso_urb" "conso_exurb" "conso_mixte"
[16] "co2" "co_typ_1" "hc"
[19] "nox" "hcnox" "ptcl"
[22] "masse_ordma_min" "masse_ordma_max" "champ_v9"
[25] "date_maj" "Carrosserie" "gamme"
Le caractère \
est utilisé comme caractère d’échappement. Ainsi:
\\
est affiché\
pour afficher le caractère
"
, la chaine de caractère sera\"
\n
sera utilisé pour un retour à la ligne\t
pour une tabulationetc…
On construit un vecteur de caractères comme un vecteur numérique avec la fonction c()
:
> x <- c("a", "b", "c")
> x
[1] "a" "b" "c"
La fonction paste()
, à laquelle on peut passer un nombre arbitraire d’arguments, permet la concaténation:
> paste("a", "b", "c")
[1] "a b c"
Si les arguments ne sont pas des chaines de caractère, R tente de les forcer:
> paste("a", "b", 1)
[1] "a b 1"
> paste("a", "b", FALSE)
[1] "a b FALSE"
Par défaut l’espace simple est utilisé comme séparateur, mais il est paramétrable:
> paste("a", "b", "c", sep="")
[1] "abc"
paste()
peut également prendre des vecteurs en argument, et procéder à la concaténation élément par élément:
> x <- c("a", "b", "c")
> y <- c("d", "e", "f")
> paste(x, y, sep="")
[1] "ad" "be" "cf"
Question
En utilisant la règle de recyclage, essayer de prédire le résultat des 2 instructions suivantes:
> paste(c("X","Y"), 1:8, sep="")
> paste(c("X","Y"), 1:5, c("a", "b"), sep="-")
Vérifier dans la console
6.7. Vecteurs d’index
On peut sélectionner une partie d’un vecteur avec l’opérateur d’indexation [ ]
.
6.7.1. Sélection par condition logique
On peut passer un vecteur logique à l’opérateur d’indexation. Dans ce cas, les éléments sélectionnés sont ceux pour lesquelles l’élément du vecteur d’indexation prend la valeur TRUE
. Ceux correspondant à la valeur FALSE
sont écartés. Par exemple:
> x <- c(100,34,NA,78,6,NA,84,NA,27,59)
> is.na(x)
[1] FALSE FALSE TRUE FALSE FALSE TRUE FALSE TRUE FALSE FALSE
> !is.na(x)
[1] TRUE TRUE FALSE TRUE TRUE FALSE TRUE FALSE TRUE TRUE
> x[is.na(x)]
[1] NA NA NA
> x[!is.na(x)]
[1] 100 34 78 6 84 27 59
C’est une façon de filtrer les valeur manquantes/non manquantes d’un vecteur.
Astuce
on peut construire des vecteur logiques complexes avec les opérateurs
&
et|
on disposera de fonction de plus haut niveau lorsqu’il s’agira de travailler sur une
data.frame
Question
Essayer de prédire le résultat de l’instruction suivante:
> (x+1)[(!is.na(x)) & x>40]
Vérifier dans la console
6.7.2. Quels indices sont TRUE ?
La fonction which()
est utile pour identifier les indices TRUE
en fonction d’un prédicat passé en argument:
> which(is.na(x))
[1] 3 6 8
> which(x>40)
[1] 1 4 7 10
6.7.3. Sélection par index
Dans ce cas les valeurs du vecteur passé à l’opérateur d’indexation doivent être dans l’ensemble {1, 2, …, length(x)}
. Les éléments correspondants sont sélectionnés et concaténés, dans cet ordre, pour construire le résultat. Le vecteur d’index peut être de longueur arbitraire:
> x
[1] 100 34 NA 78 6 NA 84 NA 27 59
> x[3]
[1] NA
> x[1:5]
[1] 100 34 NA 78 6
Question
Essayer de prédire le résultat de l’instruction suivante:
> x[c(5,4,3)]
Vérifier dans la console
6.7.4. Désélection par index
Le signe -
est utilisé pour identifier les valeurs à exclure:
> x[-(1:5)]
[1] NA 84 NA 27 59
Question
Essayer de prédire le résultat de l’instruction suivante:
> x[-c(5,4,3)]
Vérifier dans la console
6.7.5. Sélection par nom
Lorsqu’un objet posséde un attribut name pour identifier ses composants, on peut utiliser un vecteur de chaines de caractères pour sélectionner des éléments:
> fruit <- c(5, 10, 1, 20)
> names(fruit)
NULL
> names(fruit) <- c("orange", "banana", "apple", "peach")
> fruit[c("apple","orange")]
apple orange
1 5
Il est plus lisible et maintenable de sélectionner des éléments par nom, plutôt que par indice. On retrouvera cette façon de faire lorsqu’on manipulera des data.frame
dans le chapitre Data frames.
6.7.6. Affectation
On peut utiliser l’opérateur d’indexation à gauche de l’opérateur d’affectation (LHS) pour affecter des valeurs à une sous partie d’un vecteur. L’expression doit être de la forme vector[index_vector]
.
Par exemple, on remplace les valeurs manquantes par un 0:
> x[is.na(x)] <- 0
> x
[1] 100 34 0 78 6 0 84 0 27 59
Une façon (tordue) de prendre la valeur absolue:
> y[y < 0] <- -y[y < 0]
Cet exemple n’est qu’une illustration de l’utilisation de l’indexation, et on choisira évidemment la forme classique:
> y <- abs(y)
6.8. Coercition
R permet la coercition explicite ou implicite entre les objets.
La coercition explicite est effectuée avec la famille de fonctions as.xxx()
:
> a <- -1:1
> a
[1] -1 0 1
> typeof(a)
[1] "integer"
La règle est que la coercition s’applique du type le plus contraint vers le type le moins contraint, c’est à dire dans l’ordre : logical, integer, double, et character. Certaines opérations sont évidentes:
> as.character(a)
[1] "-1" "0" "1"
> as.complex(a)
[1] -1+0i 0+0i 1+0i
as.numeric()
force l’objet vers un type double
:
> as.numeric(a)
[1] -1 0 1
> typeof(as.numeric(a))
[1] "double"
Attention aux comparaisons, ==
teste l’égalité, indépendamment du type:
> a == as.numeric(a)
[1] TRUE TRUE TRUE
alors que la fonction identical()
compare également le type:
> identical(a,as.numeric(a) )
[1] FALSE
Lors de la conversion vers le type logique, seules les valeurs nulles sont FALSE
> as.logical(a)
[1] TRUE FALSE TRUE
Si la coercition n’a pas de sens, l’opération échoue:
> as.numeric(c("a", "b"))
[1] NA NA
Warning message:
NAs introduced by coercion
La coercition implicite est mise en oeuvre lorsqu’on manipule des éléments inhomogènes:
> a<-c(1,"a")
> typeof(a)
[1] "character"
> a
[1] "1" "a"
> a<-c(FALSE, "a")
> typeof(a)
[1] "character"
> a
[1] "FALSE" "a"
> a<-c(1, TRUE)
> typeof(a)
[1] "double"
> a
[1] 1 1
La coercition implicite n’est pas souhaitable pour des questions de lisibilité et de maintenance:
> as.numeric("1") < 2
[1] TRUE
est meilleur que:
> "1" < 2
[1] TRUE
6.9. Exercices
Définir les vecteurs x
et y
comme suit:
> x<-c(4,2,6)
> y<-c(1,0,-1)
Question
Essayer de prédire le résultat des instructions suivantes:
> length(x)
> sum(x)
> sum(x^2)
> x+y
> x*y
> x-2
> x^2
Vérifier dans la console
Question
Essayer de prédire le résultat des instructions suivantes:
> 7:11
> seq(2,9)
> seq(4,10,by=2)
> seq(3,30,length=10)
> seq(6,-4,by=-2)
Vérifier dans la console
Question
Essayer de prédire le résultat des instructions suivantes:
> rep(2,4)
> rep(c(1,2),4)
> rep(c(1,2),c(4,4))
> rep(1:4,4)
> rep(1:4,rep(3,4))
Vérifier dans la console
Question
Use the rep function to define simply the following vectors in R:
[1] 6 6 6 6 6 6
[1] 5 8 5 8 5 8 5 8
[1] 5 5 5 5 8 8 8 8
Considérons maintenant l’instruction suivante:
x <- c(5,9,2,3,4,6,7,0,8,12,2,9)
Question
Essayer de prédire le résultat des indexations suivantes:
> x[2]
> x[2:4]
> x[c(2,3,6)]
> x[c(1:5,10:12)]
> x[-(10:12)]
Vérifier dans la console
6.10. Application : population urbaine
Cet exercice d’application utilise un jeu de données sur la population des principales villes françaises entre 1962 et 2012.
6.10.1. Créer l’environnement de travail
Démarrer R Studio
S’assurer qu’aucun projet n’est ouvert, sinon R Studio > File > Close Project
Créer un nouveau projet « Population » R Studio > File > New project... > New Directory > New Project
Le jeu de données concernant la population des 20 plus grandes villes de France entre 1962 et 2012 est stocké au format .RData
. Enregistrer ce fichier
dans le répertoire du projet.
Indication
Immédiatement après la création du projet, le répertoire doit contenir un dossier masqué et deux fichiers, dont le fichier .RData
téléchargé ci dessus..

Pour extraire les données vers l’espace de travail, cliquer sur le nom du fichier dans le navigateur de fichiers de R Studio.
Plusieurs vecteurs doivent apparaître dans l’explorateur d’objets.
6.10.2. Exploration
On va manipuler ces différents vecteurs pour explorer l’évolution de la population française, dans quelques unes des plus grandes villes, entre 1962 et 2012.
A l’aide de la console R, répondre aux questions suivantes :
Combien de villes sont représentées dans les données ? Lesquelles ?
Combien d’années sont représentées dans les données ? Lesquelles ?
En quelle année Angers a t-elle dépassé pour la première fois 150.000 habitants ?
Quelle est la population moyenne de Bordeaux sur les 3 derniers recensements ?
Calculer l’évolution de la population parisienne à chacun des recensements ? Utiliser la fonction
diff()
. Commenter la taille et la composition du vecteur obtenu.
Quelles sont les années pour lesquelles l’évolution de population a suivi la même pente (positive ou négative) à Lyon et Toulouse ? La fonction
sign()
peut être utile.