Li

Listes en R

1 exercice

À propos de Listes

Une list en R est une collection ordonnée d'éléments, qui se distingue des vectors de plusieurs façons :

  • Les éléments peuvent être de types différents (par exemple mélanger des numeric avec des character).
  • Les éléments peuvent être des structures complexes (par exemple des vecteurs, d'autres listes, etc.).
  • L'accès aux éléments utilise une syntaxe un peu différente.

Les analogies avec d'autres langages sont imparfaites. Une list en R ressemble un peu à un dictionnaire Python, mais la list est ordonnée et on peut y accéder par un indice numérique. Elle ressemble aussi un peu à une struct du C, à ceci près qu'on peut facilement étendre la list à l'exécution.

Création de listes

Donner des noms (souvent appelés « tags ») aux éléments est plus courant avec les listes qu'avec les vecteurs :

list(x = 5.3, y = 4.2, color = "blue")
#> $x
#> [1] 5.3

#> $y
#> [1] 4.2

#> $color
#> [1] "blue"

Cependant, les tags sont facultatifs, et R se contente alors d'utiliser des numéros d'indice :

list(5.3, 4.2, "blue")
#> [[1]]
#> [1] 5.3

#> [[2]]
#> [1] 4.2

#> [[3]]
#> [1] "blue"

Accès aux éléments d'une liste

Il y a trois façons de faire, chacune utile dans des contextes différents.

1. Avec la notation $tag

Très courant si les noms des tags sont connus à l'avance.

point <- list(x = 5.3, y = 4.2, color = "blue")
#> point$x
#> [1] 5.3
#> point$color
#> [1] "blue"

2. Avec la notation [[tag]]

Cela a l'avantage de permettre de choisir le nom du tag à l'exécution. Remarque les doubles crochets.

want <- "y"
point[[want]] # same as point$y
#> [1] 4.2

3. Avec l'indice de position

Cela fonctionne que la liste ait des tags ou non. Là encore, les crochets sont doublés.

point[[3]] # same as point$color
#> [1] "blue"

Ajout et suppression d'éléments

C'est simple : affecter une valeur à un élément le modifie s'il existe, ou l'insère s'il est nouveau.

point$color <- "red"
point$trust <- TRUE

# str() gives more compact output than the default display
str(point) 
#> List of 4
#>  $ x    : num 5.3
#>  $ y    : num 4.2
#>  $ color: chr "red"
#>  $ trust: logi TRUE

Pour supprimer un élément dont on ne veut plus, il suffit de lui affecter NULL.

point$trust <- NULL
str(point)  
#> List of 3
#>  $ x    : num 5.3
#>  $ y    : num 4.2
#>  $ color: chr "red"

Les listes sont des « vecteurs récursifs »

La classe vector est techniquement appelée atomic vector, car elle ne peut contenir que des valeurs atomiques : numeric, character, boolean, etc. Comme une list peut contenir d'autres listes, on l'appelle aussi recursive vector.

En plus d'être un point de nomenclature technique, cela rappelle que les listes peuvent avoir une structure arbitrairement complexe. Il incombe au programmeur ou à la programmeuse de comprendre ce qui sera fourni lorsqu'on accède à un élément de la liste.

Pour en savoir plus sur l'indexation des listes

Certains exemples ci-dessus utilisent des doubles crochets [[ ]] pour accéder aux éléments d'une liste. Cela tente d'aplatir l'élément vers son type sous-jacent, ce qui est utile si tu veux simplement un nombre ou une string.

Avec des crochets simples [ ], cet aplatissement n'a pas lieu : la valeur renvoyée est une sous-liste.

point[["color"]]
#> [1] "red"  # flattened

point["color"]
#> $color
#> [1] "red"  # sublist

Même si la sous-liste n'est pas ce qu'un programmeur R débutant souhaite probablement, il faut en être conscient. Pour une souplesse maximale, de nombreuses fonctions standard de R renvoient une list, même lorsqu'elle ne contient qu'une seule valeur atomique comme ici.

Pour convertir en vecteur, il y a deux possibilités.

  1. Prends le premier élément avec [[1]]
  2. Utilise la fonction unlist().
pt <-point["color"]

pt[[1]]
#> [1] "red" # simple 1-element vector

unlist(pt)
#> color 
#> "red"  # 1-element vector with name

Fais attention avec unlist(). Aplatir la structure est utile dans ce cas simple, mais peut réserver des surprises avec des éléments de liste plus compliqués.

Advanced

Représentation interne

Une list, comme un vector atomique, est stockée de manière contiguë. La différence est que les vecteurs numériques et booléens stockent des valeurs, tandis que la liste stocke des références vers des objets situés ailleurs en mémoire.

Savoir cela est rarement important pour une personne qui utilise R, mais dans une communauté polyglotte comme Exercism, cela peut être utile aux programmeurs qui connaissent d'autres langages.

Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet

Apprends Listes