Menu

Les listes en R : créer, accéder ([[ , $ ou [) et modifier

Les listes sont le conteneur fourre-tout de R : types mélangés, structures imbriquées, data frames entiers. La compétence clé est de savoir quand [ renvoie une liste plus petite et quand [[ renvoie l'élément lui-même.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

Une liste contient n'importe quoi

Un vecteur a une règle stricte : chaque élément doit être du même type. Une liste n'a pas cette règle. Chaque élément d'une liste peut être d'un type différent, d'une longueur différente, voire une autre liste. C'est le conteneur polyvalent de R :

length() rapporte 4 - quatre éléments, même si l'un d'eux (scores) contient lui-même trois nombres. Une liste compte ses compartiments, pas ce qu'il y a dedans. str() (structure) est le moyen le plus rapide de voir ce qu'une liste contient réellement - une ligne par élément avec son nom, son type et un aperçu. Fais de str() un réflexe : dès qu'une fonction te rend quelque chose et que tu n'es pas sûr de ce que c'est, passe-lui str().

Les noms sont facultatifs (list(1, "a", TRUE) est légal) mais valent presque toujours la peine - une liste nommée se documente elle-même.

Les trois façons d'entrer : [, [[ et $

C'est la partie des listes que tout le monde rate une fois, alors mettons-la parfaitement au clair. Il y a trois opérateurs d'accès, et ils font deux travaux différents :

  • [ renvoie une liste plus petite - un conteneur de même nature, contenant ce que tu as sélectionné.
  • [[ renvoie l'élément lui-même - la vraie valeur à l'intérieur du compartiment.
  • $ est un raccourci pour [[ avec un nom littéral : person$age c'est person[["age"]].

La différence est invisible quand tu affiches distraitement et très visible dès que tu essaies de calculer :

person["scores"] a la classe "list" - une liste de longueur 1 avec le vecteur de scores dedans. person[["scores"]] a la classe "numeric" - le vecteur lui-même, prêt pour mean(). Appelle mean() sur la version à crochet simple et tu obtiens une erreur disant que l'argument n'est pas numérique ; ce message d'erreur est presque toujours le signe que tu as utilisé [ là où tu voulais [[.

Une métaphore qui reste : une liste est un train. [ te donne un train plus court - toujours un train. [[ ouvre un wagon et te tend la cargaison.

Alors quand [ est-il le bon outil ? Quand tu veux plusieurs éléments et que tu veux les garder emballés :

Tu ne peux pas extraire deux éléments « eux-mêmes » d'un coup - deux valeurs ont besoin d'un conteneur - donc la sélection multiple est toujours à crochet simple, et donne toujours une liste.

Une différence de plus : $ utilise l'appariement partiel (person$sc trouve scores si c'est non ambigu), ce qui est pratique en console et risqué dans les scripts. Dans du code qui doit continuer à marcher, préfère [[ avec le nom complet - il accepte aussi un nom stocké dans une variable, ce que $ ne sait pas faire.

Ajouter, modifier, supprimer

Les listes grandissent et rétrécissent par simple affectation - aucune méthode d'ajout spéciale nécessaire :

  • Affecter à un nom qui n'existe pas encore ajoute l'élément.
  • Affecter à un nom existant le remplace.
  • Affecter à la position length(x) + 1 ajoute un élément sans nom à la fin.
  • Affecter NULL supprime entièrement l'élément - la liste raccourcit. (C'est le seul endroit où NULL agit comme une commande de suppression ; si tu dois réellement stocker « rien » dans un compartiment, utilise x["k"] <- list(NULL).)

Pour coller deux listes bout à bout, c() fonctionne sur les listes comme sur les vecteurs : c(list_a, list_b) renvoie une seule liste plus longue.

Listes imbriquées

Comme un élément de liste peut être une autre liste, les listes s'imbriquent à n'importe quelle profondeur - ce qui en fait la forme naturelle de R pour des données structurées comme du JSON analysé ou des résultats groupés :

Descendre dedans revient simplement à enchaîner les accesseurs - chaque $ ou [[ descend d'un niveau. Quand une structure imbriquée devient confuse, str(company) montre tout l'arbre d'un coup, et str(company, max.level = 1) ne montre que la couche supérieure.

Aplatir avec unlist()

unlist() réduit une liste - aussi profondément imbriquée soit-elle - en un seul vecteur :

Deux choses à remarquer. D'abord, unlist() construit des noms pour toi (math1, math2, art) pour que tu puisses encore savoir d'où vient chaque valeur. Ensuite - et c'est le piège - un vecteur ne contient qu'un type, donc aplatir une liste hétérogène convertit tout vers le type le plus souple présent. Le nombre 1 est revenu sous forme de chaîne "1". Si tu aplatis et que tes nombres deviennent du texte, la liste n'était pas aussi uniforme que tu le pensais.

Pourquoi les listes comptent

Les listes peuvent sembler un sujet de débutant qu'on dépasse. C'est l'inverse - elles sont porteuses dans tout le langage :

  • Les fonctions qui renvoient plusieurs choses renvoient une liste. Les fonctions R renvoient un seul objet ; une liste permet à cet objet unique de transporter une valeur ajustée ici, une table de coefficients là. Quand tu lances une régression, l'objet modèle que tu récupères est une liste (grande, avec une classe) - un str() dessus le prouve.
  • Un data frame est une liste de colonnes - des vecteurs de longueurs égales avec un comportement supplémentaire par-dessus. Tout ce que tu viens d'apprendre ($, [[, affecter NULL pour retirer un élément) s'applique mot pour mot aux colonnes de data frame.
  • La famille apply - lapply() et compagnie - prend une liste, applique une fonction à chaque élément et rend une liste. Listes en entrée, listes en sortie, c'est la forme standard du calcul répété en R.

Ce que tu retiens

  • Les listes contiennent n'importe quoi : types mélangés, longueurs inégales, autres listes, data frames entiers.
  • [ renvoie une liste plus petite ; [[ renvoie l'élément lui-même ; $ c'est [[ avec un nom littéral. Tu veux calculer ? Il te faut [[ ou $.
  • Ajoute en affectant à un nouveau nom, supprime en affectant NULL, combine avec c().
  • unlist() aplatit en vecteur et convertit les types mélangés au passage - vérifie la classe du résultat.
  • Les data frames sont des listes de colonnes, donc ces connaissances se transfèrent directement.

Prochaine étape : les matrices - la contrepartie en lignes et colonnes, d'un seul type, de la liste.

Questions fréquentes

Quelle est la différence entre [ et [[ en R ?

Les crochets simples [ renvoient toujours une liste contenant les éléments sélectionnés - un conteneur plus petit de même nature. Les crochets doubles [[ vont chercher à l'intérieur et renvoient l'élément lui-même. Si x$scores contient un vecteur numérique, x["scores"] est une liste de longueur 1 et x[["scores"]] est le vecteur numérique. Utilise [[ (ou $) quand tu veux réellement travailler avec la valeur.

Comment ajouter un élément à une liste en R ?

Affecte à un nom qui n'existe pas encore : x$email <- "rosa@example.com" ou x[["email"]] <- .... La liste grandit automatiquement. Pour ajouter sans nom, affecte à la position suivante : x[[length(x) + 1]] <- value. Pour supprimer un élément, affecte-lui NULL : x$email <- NULL.

Comment convertir une liste en vecteur en R ?

unlist(x) aplatit une liste (y compris imbriquée) en un seul vecteur. Comme un vecteur ne contient qu'un type, tout est converti vers le type le plus souple présent - une liste de nombres et de chaînes devient un vecteur entièrement character. Vérifie la class() du résultat après avoir aplati.

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER