Les listes dans R

Les listes dans R

Les listes peuvent être récursives, ce qui signifie que vous pouvez avoir des listes dans les listes. Voici un exemple:

  1. > b <- list(u = 5, v = 12)
  2. > c <- list(w = 13)
  3. > a <- list(b,c)
  4. > a
  5. [[1]]
  6. [[1]]$u
  7. [1] 5
  8. [[1]]$v
  9. [1] 12
  10. [[2]]
  11. [[2]]$w
  12. [1] 13
  13. > length(a)
  14. [1] 2
Source code
Ce code fait en une liste à deux composants, chaque composant lui-même étant également une liste.
La fonction de concaténation c () a un argument optionnel récursif, qui contrôle si l'aplatissement se produit lorsque des listes récursives sont combinées.

  1. > c(list(a=1,b=2,c=list(d=5,e=9)))
  2. $a
  3. [1] 1
  4. $b
  5. [1] 2
  6. $c
  7. $c$d
  8. [1] 5
  9. $c$e
  10. [1] 9
  11. > c(list(a=1,b=2,c=list(d=5,e=9)),recursive=T)
  12. a b c.d c.e
  13. 1 2 5 9
Source code
Dans le premier cas, nous avons accepté la valeur par défaut de récursive, qui est FALSE, et a obtenu une liste récursive, la composante c de la liste principale elle-même étant une autre liste. Dans le deuxième appel, avec un ensemble récursif à TRUE, nous avons obtenu une liste unique; Seuls les noms semblent récursifs. (Il est étrange que le réglage récursif sur TRUE donne une liste non récurrente.)
Rappelons que notre premier exemple de listes était constitué d'une base de données d'employés.
J'ai mentionné que, puisque chaque employé était représenté comme une liste, la base de données entière serait une liste de listes. C'est un exemple concret de listes récursives.

Deux fonctions sont utiles pour appliquer des fonctions aux listes: 1application et sappliée.

 

Utilisation des fonctions lapply () et sapply ()
La fonction lapply ()  fonctionne comme la fonction matrix apply (), appelant la fonction spécifiée sur chaque composant d'une liste (ou vecteur contraint à une liste) et renvoie une autre liste. Voici un exemple:

  1. > lapply(list(1:3,25:29),median)
  2. [[1]]
  3. [1] 2
  4. [[2]]
  5. [1] 27
Source code

R a appliqué la fonction median() à 1: 3 et à 25:29, en renvoyant une liste composée de 2 et 27.
Dans certains cas, comme l'exemple ici, la liste renvoyée par lapply () pourrait être simplifiée pour un vecteur ou une matrice. C'est exactement ce que sapply () fait.

  1. > sapply(list(1:3,25:29),median)
  2. [1] 2 27
Source code
Vous avez vu un exemple de sortie matricielle à la section 6 Là, nous avons appliqué une fonction vectorisée vectorielle -une fonction dont la valeur de retour est un vecteur, dont chacun des composants est vectorisé- à une entrée vectorielle. En utilisant sapply (), plutôt que d'appliquer la fonction directement, nous a donné la forme matricielle souhaitée dans la sortie.

 

 

 

Si les composants d'une liste ont des étiquettes, comme c'est le cas avec le nom, le salaire et l'union pour j à la section 1, vous pouvez les obtenir via les names():
  1. > names(j)
  2. [1] "name" "salary" "union"
Source code
Pour obtenir les valeurs, utilisez unlist ():
  1. > ulj <- unlist(j)
  2. > ulj
  3. name salary union
  4. "Joe" "55000" "TRUE"
  5. > class(ulj)
  6. [1] "character"
Source code
La valeur de retour de unlist () est un vecteur, dans ce cas, un vecteur de chaînes de caractères. Notez que les noms d'élément dans ce vecteur proviennent des composants dans la liste d'origine.
D'autre part, si nous devions commencer par des chiffres, on obtiendrait des nombres.
  1. > z <- list(a=5,b=12,c=13)
  2. > y <- unlist(z)
  3. > class(y)
  4. [1] "numeric"
  5. > y
  6. a b c
  7. 5 12 13
Source code
Donc, la sortie de un1ist () dans ce cas était un vecteur numérique. Qu'en est-il d'un cas mixte?
  1. > w <- list(a=5,b="xyz")
  2. > wu <- unlist(w)
  3. > class(wu)
  4. [1] "character"
  5. > wu
  6. a b
  7. "5" "xyz"
Source code
Ici, R a choisi le dénominateur le moins commun: les chaînes de caractères. Cela ressemble à une sorte de structure de priorité, et c'est. Comme l'aide de R pour unlist () déclare:
Dans la mesure du possible, les composants de la liste sont forcés à un mode commun lors de l'élimination, de sorte que le résultat finit souvent par être un vecteur de caractères. Les vecteurs seront forcés au type le plus élevé des composants dans la hiérarchie NULL < raw < logical < integer < real < complex < character < list < expression:: les pairlists sont traités comme des listes.
Mais il y a autre chose à régler ici. Bien que wu soit un vecteur et non une liste, R a donné à chacun des éléments un nom. Nous pouvons les supprimer en indiquant NULL, comme vous l'avez vu à la Section 2.11.
  1. > names(wu) <- NULL
  2. > wu
  3. [1] "5" "xyz"
Source code
Nous pouvons également supprimer les noms des éléments directement avec unname (), comme suit:
  1. > wun <- unname (wu)
  2. > wun
  3. [1] "5" "xyz"
Source code
Cela a également l'avantage de ne pas détruire les noms dans wu, au cas où ils seraient nécessaires plus tard. Si elles ne seront pas nécessaires plus tard, nous pourrions tout simplement attribuer de nouveau à wu au lieu d'être mentionné dans la déclaration précédente.

 

Maintenant que vous avez vu un exemple simple de création d'une liste, regardons comment accéder et travailler avec les listes.


1 Indexer la liste
Vous pouvez accéder à un composant de liste de différentes façons:

  1. > j$salary
  2. [1] 55000
  3. > j[["salary"]]
  4. [1] 55000
  5. > j[[2]]
  6. [1] 55000
Source code
Nous pouvons nous référer à la liste des composants par leurs indices numériques, en traitant la liste en tant que vecteur. Cependant, notez que, dans ce cas, nous utilisons des brackets double au lieu de simples. Donc, il existe trois façons d'accéder à un composant individuel c d'une liste 1ère et de le renvoyer dans le type de données de c:
• 1er $ c
• 1er [["c"]]
• 1er [[i]], où i est l'index de c au 1er
Chacune d'entre elles est utile dans différents contextes, comme vous le verrez dans les exemples suivants. Mais notez la phrase de qualification, "renvoyez-la dans le type de données de c". Une alternative à la deuxième et à la troisième techniques répertoriées consiste à utiliser des brackets simples plutôt que des crochets double:
• 1er ["c"]
• 1er [i], où i est l'index de c au 1er
Les éléments de liste d'accès à l'indexation à une seule parenthèse et à double bracket en mode index vectoriel. Mais il existe une différence importante par rapport à l'indexation vectorielle (atomique) ordinaire. Si des supports individuels [] sont utilisés, le résultat est une autre liste - une sous-partition de l'original. Par exemple, en continuant l'exemple précédent, nous avons ceci:

  1. > j[1:2]
  2. $name
  3. [1] "Joe"
  4. $salary
  5. [1] 55000
  6. > j2 <- j[2]
  7. > j2
  8. $salary
  9. [1] 55000
  10. > class(j2)
  11. [1] "list"
  12. > str(j2)
  13. List of 1
  14. $ salary: num 55000
Source code

L'opération de sous-ensemble a renvoyé une autre liste consistant en les deux premiers composants de la liste d'origine j. Notez que le mot retourné est logique, car les brackets d'index sont des fonctions. Ceci est similaire à d'autres cas que vous avez vus pour les opérateurs qui ne semblent pas être des fonctions, comme par exemple +.
En revanche, vous pouvez utiliser deux brackets [[]] pour référencer uniquement un seul composant, le résultat ayant le type de ce composant.

  1. > j[[1:2]]
  2. Error in j[[1:2]] : subscript out of bounds
  3. > j2a <- j[[2]]
  4. > j2a
  5. [1] 55000
  6. > class(j2a)
  7. [1] "numeric"
Source code

2 Ajout et suppression d'éléments de liste
Les opérations d'ajout et de suppression d'éléments de liste se produisent dans un nombre surprenant de contextes. Ceci est particulièrement vrai pour les structures de données dans lesquelles les listes constituent la base, telles que les trames de données et les classes R.
Les nouveaux composants peuvent être ajoutés après la création d'une liste.


  1. > z <- list(a="abc",b=12)
  2. > z
  3. $a
  4. [1] "abc"
  5. $b
  6. [1] 12
  7. > z$c <- "sailing" # ajouter un composant c
  8. > # c est-il ajouter?
  9. > z
  10. $a
  11. [1] "abc"
  12. $b
  13. [1] 12
  14. $c
  15. [1] "sailing"
Source code

 L'ajout de composants peut également être effectué via un index vectoriel:

  1. > z[[4]] <- 28
  2. > z[5:7] <- c(FALSE,TRUE,TRUE)
  3. > z
  4. $a
  5. [1] "abc"
  6. $b
  7. [1] 12
  8. $c
  9. [1] "sailing"
  10. [[4]]
  11. [1] 28
  12. [[5]]
  13. [1] FALSE
  14. [[6]]
  15. [1] TRUE
  16. [[7]]
  17. [1] TRUE
Source code

Notez que lors de la suppression de z $ b, les indices des éléments après avoir déplacé vers le haut par 1. Par exemple, l'ancien z [[4]] est devenu z [[3]].
Vous pouvez également concaténer des listes.

  1. > c(list("Joe", 55000, T),list(5))
  2. [[1]]
  3. [1] "Joe"
  4. [[2]]
  5. [1] 55000
  6. [[3]]
  7. [1] TRUE
  8. [[4]]
  9. [1] 5
Source code


3 Obtenir la taille d'une liste
Étant donné qu'une liste est un vecteur, vous pouvez obtenir le nombre de composants dans une liste via 1 length ().

  1. > length(j)
  2. [1] 3
Source code