2.6 Les listes
Dans les chapitres précédents, nous avons vu les 5 types atomiques principaux que sont les vecteurs de type integer
, double
,complex
,character
et logical
. Nous allons voir dans ce chapitre un nouveau type de données, les listes.
Déclarer une liste
Une liste est trés proche d'un vecteur, si ce n'est qu'elle permet de stocker des données de types atomiques différents. Voici comment déclarer une liste :
washington = list(1, 67, "George", "Washington", FALSE)
Il suffit d'utiliser la fonction list()
et d'écrire entre les parenthèses les différents élements de notre liste, séparés entre eux par des virgules. On voit ici que les deux premiers éléments de notre liste sont des double
, les deux suivants des chaines character
et le dernière élement un booléen de type logical
.
Une liste est donc très pratique pour regrouper ensemble des données de types différentes, ce qu'un vecteur ne peut pas faire. Dans notre exemple, la liste associée à la variable washington
regroupe ainsi le numéro du président dans l'histoire des Etats-unis, son âge, son prénom, son nom, et un boolean qui indique si il a été assassiné ou non. On peut ainsi regrouper toutes les informations à son propos dans une seule variable de type list
.
On peut facilement vérifier le type list
de notre variable à l'aide de typeof()
que nous connaissons :
typeof(washington) #affiche "list"
Afficher une liste
Pour afficher ce que contient notre liste, il suffit de d'écrire son nom dans la console ou d'utiliser l'instruction print()
, comme nous avons l'habitude de le faire :
print(washington)
Le contenu de la liste s'affiche alors dans la console, sous cette forme :
Accéder et modifier les éléments d'une liste
Nous pouvons accéder à l'information stockée dans une liste de plusieurs façons différente. La première consiste à utiliser les doubles crochets, et à indiquer entre le numéro de l'élément à afficher. Ici, on affiche le troisiéme élément de notre liste :
washington[[3]] #affiche "George"
Remarque : Comme pour les vecteurs, les éléments d'une liste sont numérotés à partir de 1.
Le double crochet nous permet d'accéder directement à l'élément en question. Ici, le troisiéme élément stocké dans notre liste est une chaine de caractére de type character
qui est récupérée avec notre instruction washington[[3]]
.On peut le vérifier en regardant le type de la donnée obtenue :
typeof(washington[[3]]) #affiche "character"
Modifier un élément :
De la même façon que pour les vecteurs, il est possible de modifier l'élément selectionné, en le replacant par une nouvelle valeur :
washington[[1]] = "1er président des Etats-Unis"
Il est aussi possible d'ajouter un nouvel élément à la liste, en l'écrivant à une place encore vide.
washington[[6]] = "nouvelle donnée"
Remarque : Comme dans le cas d'un vecteur, si vous ajouter une donnée en laissant des cases vides, celles-ci seront automatiquement remplis avec la valeur NULL
. Si on affecte rien à la place 6 mais qu'on affecte quelque chose à une place supérieure (supposons que l'on a ajouté un élément à la place 7), on voit que la place 6 contient la valeur NULL
:
Obtenir une sous-liste
Il existe une seconde façon d'extraire les données d'une liste, en utilisant les crochets simples []
au lieu des crochets doubles [[]]
. La différence est que avec les crochets doubles, nous obtenons la donnée contenue dans la liste, alors que les crochets simples récupérent eux une sous-liste qui correspond aux éléments selectionnés.
Regardons un exemple :
washington = list(1, 67, "George", "Washington", FALSE)
print(washington[3])
Ce code ne vas pas affficher la chaine de caractéres Washington
mais va afficher une liste, qui contient comme seul élément la chaine Washington
, qui se trouve bien en 3éme position.
Nous avons ainsi créee une sous-liste a partir de la premiére liste, qui ne contient qu'un seul élément. On peut vérifier qu'il s'agit bien d'une liste en affichant le type :
typeof(washington[3]) #affiche "list"
Les crochets simples ont ainsi l'avantage de préserver la structure des données : ils permettent d'extraire une sous-liste d'une liste existance. Si vous voulez accéder directement à la donnée "brute" stockée dans un élément de la liste, il faut utiliser les crochets doubles.
L'avantage des crochets simples et qu'ils permettent d'extraire plusieurs éléments d'une liste, ce qui est impossible avec les crochets doubles. Si on souhaite récupérer le nom et le prénom du premier président des Etats-Unis, il suffit de faire comme ceci :
print(washington[c(3, 4])
Et la console affichera la sous liste correspondante :
De façon plus générale, toutes les façons de faire que nous avons vu au chapitre précédent pour extraire de l'information d'un vecteur fonctionnent aussi avec les listes et les crochets simples []
. Vous pouvez utiliser le signe -
pour exclure une colonne, un vecteur de logicial
, etc.
Notez que extraire plusieurs éléments d'une liste ne fonctionnerai pas avec les crochets doubles, car extraire plusieurs éléments de natures différentes revient à créer... une liste ! Et c'est le rôle des crochets simples que de permettre d'éxtraire une sous liste.
La différence entre les crochets simples et double est souvent source d'erreur chez les débutants : réfléchissez bien pour savoir si vous voulez extraire une sous liste (ou plusieurs éléments), ou une donnée de la liste en particulier.
Nommer les éléments d'une liste
Nous pouvons nommer les élements d'une liste de la même façon que l'on nomme les éléments d'un vecteur, à l'aide de la fonction names()
. Cela nous permet de facilement voir à quoi correspond chaque élement de la liste. Nommons les information contenues dans notre liste washington
:
washington = list(1, 67, "George", "Washington", FALSE)
names(washington) = c("numero_president", "age", "prenom", "nom", "assasinat")
On peut alors afficher le contenu de la liste dans la console :
Nous pouvons voir que chaque élément est maintenant identifié par son nom, précédé du signe $
, et non plus affiché sous la forme [[i]]
.
Accéder et modifier les éléments d'une liste nommée
On peut accéder aux éléments d'une liste nomée en utilisant leur nom, exactement comme avec un vecteur nommée. Il suffit pour cela d'écrire le nom de l'élément aprés le signe $
et le nom de la variable contenant notre liste. Voici comme récupérer l'age du premier président des Etats-Unis avec cette méthode :
print(washington$age) #affiche 67
Vous pouvez directement ajouter des éléments à la liste de cette façon, en les nommant :
washington = list() #on créer une liste vide
washington$numero_president = 1 #on ajoute des éléments nommés à la liste
washington$age = 67
#etc.
Chaque nouvel élément ajouté ainsi est ajouté à la fin de la liste, ce qui évite d'avoir des trous comme quand on ajoute un élément avec un numéro trop grand.
Liste de vecteurs
Une liste peut contenir des vecteurs comme éléments. En réalité, c'est déjà le cas dans les listes que nous avons créee précédement. En effet, toutes les données en R que nous avons vu jusqu'a présent sont des vecteurs : une chaine de caractére est un vecteur de character
de dimension 1, un nombre est un vecteur de dimension 1 etc.
Supposons que l'on souhaite regrouper les informations sur les 3 premiers présidents des Etats-Unis. Il nous suffit de déclarer la liste suivante, composée de vecteurs :
order = c(1, 2, 3)
ages = c(67, 90, 83)
prenoms = c("George", "John", "Thomas")
noms = c("Washingon", "Adams", "Jefferson")
assassinat = c(FALSE, FALSE, FALSE)
#On déclare une liste pour contenir toutes ses informations :
presidents = list(order, ages, prenoms, noms, assassinat)
On peut alors afficher la liste en question :
Il est également possible de faire une liste de liste. Cela peut être pratique si l'on souhaite regrouper les informations concernant chaque président dans une liste, puis faire une liste où chaque élément est la liste des informations sur chaque président.
Les listes sont une structure de données qui sera très utile pour la partie avancée de ce cours, aussi il est important de bien en comprendre le fonctionnement.
A retenir :
- Les listes permettent de stocker des données de différentes natures, ce que les vecteurs ne peuvent pas faire. On déclare une liste avec la fonction
list()
. - Les listes sont de type
list
. - On peut accéder aux éléments contenu dans une liste avec la syntaxe à double crochets
my_list[[i]]
. Cela ne permet de récupérer qu'un seul élément. - Il existe une syntaxe avec simples crochets qui permet d'extraire une sous-liste d'éléments :
my_list[c(1,3)]
. - On peut modifier les éléments d'une liste en y accédant et en les remplacant comme avec les vecteurs.
- Les éléments d'une liste peuvent être nommés avec la fonction
names(my_list)
et on peut accéder aux éléments avec la syntaxe suivante :mylist$element
. - Une liste peut contenir des vecteurs comme éléments.