Menu

Filtrer et extraire des données en R (subset, [ ], dplyr filter)

Toutes les façons de garder les lignes et colonnes que tu veux : masques logiques avec crochets, le one-liner subset(), %in%, les pièges des NA, et filter() et select() de dplyr.

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

Filtrer les lignes : le masque logique

Pour filtrer un data frame en R, mets une condition dans la position des lignes entre crochets : df[condition, ]. La condition s'évalue en un vecteur de TRUE/FALSE, un par ligne, et R garde les lignes TRUE :

Lis scores[scores$score > 80, ] de l'intérieur vers l'extérieur : scores$score > 80 produit TRUE FALSE TRUE TRUE FALSE, et les crochets gardent les lignes 1, 3 et 4. La virgule finale n'est pas optionnelle. Les crochets sur un data frame prennent [lignes, colonnes] ; laisser l'emplacement des colonnes vide signifie « toutes les colonnes ». Oublie la virgule et tu indexes des colonnes à la place - l'une des erreurs de débutant les plus courantes en R.

Remarque que les numéros de lignes affichés sont 1 3 4, pas 1 2 3 - le filtrage conserve les étiquettes de lignes d'origine. Sans danger, mais ça surprend.

Conditions multiples : & et | (pas &&)

Combine les conditions avec & (ET) et | (OU). Chaque condition a droit à sa propre comparaison complète :

Le piège : R a aussi && et ||, et ils ne sont pas interchangeables avec & et | ici. Les formes doubles marchent sur des valeurs uniques (elles existent pour les conditions if) ; face à des colonnes entières, R moderne (4.3+) s'arrête avec une erreur du type 'length = 5' in coercion to 'logical(1)', et les anciennes versions de R ne comparaient silencieusement que la première ligne - sans doute pire. Entre crochets, toujours les simples & et |. La doc sur les opérateurs couvre la distinction en détail.

%in% : tester l'appartenance à un ensemble de valeurs

Quand une colonne doit correspondre à l'une de plusieurs valeurs, n'enchaîne pas des == avec | - utilise %in% :

x %in% set renvoie TRUE partout où x est l'une des valeurs de set. Ça se lit mieux que status == "pending" | status == "shipped", ça passe à l'échelle pour n'importe quel nombre de valeurs, et ça se nie proprement : !(orders$status %in% c("refunded")).

Sélectionner des colonnes

L'emplacement des colonnes entre crochets prend des noms ou des positions :

Deux remarques. Sélectionner par nom survit à un réordonnancement des colonnes ; sélectionner par position (scores[, c(1, 3)]) casse le jour où quelqu'un insère une colonne. Et demander une seule colonne renvoie un simple vecteur, pas un data frame - c'est pourquoi le second print() affiche 91 88 sans tableau autour. Quand tu dois garder la forme de data frame, ajoute drop = FALSE : scores[, "score", drop = FALSE].

subset() : le one-liner sympathique de R de base

R de base fournit un wrapper qui traite lignes et colonnes en un seul appel lisible - pas de $, pas de comptabilité de virgules :

Dans subset() tu écris les noms de colonnes nus (score, pas scores$score) - il les évalue par rapport au data frame. Ça s'appelle l'évaluation non standard, et elle vient avec une réserve documentée : elle résout les noms à l'exécution d'une manière qui se comporte mal dans tes propres fonctions (une variable nommée score dans ta fonction peut être masquée par une colonne nommée score). La règle générale, tout droit sortie de ?subset : super en interactif, à éviter en programmation - utilise l'indexation par crochets dans ce cas.

Le piège des NA

Une comparaison avec NA produit NA, pas FALSE - et le filtrage par crochets garde les lignes au masque NA comme des lignes pleines de NA :

Le premier résultat contient une ligne parasite de NA parce que la condition de la ligne 2 n'était ni TRUE ni FALSE. Le remède est d'exiger !is.na() explicitement. subset() et le filter() de dplyr suppriment tous deux silencieusement les lignes à condition NA - pratique, mais sache que ça se produit. La doc sur les valeurs manquantes explique pourquoi NA se propage comme ça.

La méthode dplyr : filter() et select()

Le package dplyr découpe le travail en deux verbes - filter() pour les lignes, select() pour les colonnes - avec des noms de colonnes nus et sans répétition de df$ (statique ; le bac à sable n'exécute que R de base) :

library(dplyr)

scores |> filter(score > 80)
scores |> filter(score > 80, team == "red")     # comma = AND
scores |> filter(status %in% c("pending", "shipped"))
scores |> select(name, score)
scores |> filter(team == "red") |> select(name, score)

filter() supprime automatiquement les lignes à condition NA et renvoie toujours un data frame (jamais un vecteur nu), ce qui élimine les deux pièges de R de base ci-dessus. La contrepartie est une dépendance à un package et les mêmes réserves d'évaluation non standard que subset() - vois l'intro à dplyr pour le tour complet des verbes.

Ce que tu retiens

  • df[condition, ] est l'idiome fondamental - et la virgule est obligatoire.
  • Combine les conditions avec les simples & et | ; && provoque une erreur sur les vecteurs.
  • %in% bat les == enchaînés pour tester un ensemble de valeurs.
  • Sélectionne les colonnes par nom, et souviens-toi qu'une colonne seule retombe en vecteur sauf avec drop = FALSE.
  • subset() est le one-liner agréable en interactif ; les crochets sont la version programmable.
  • Les comparaisons avec NA produisent des lignes fantômes entre crochets - protège avec !is.na().

Prochaine étape : ajouter et transformer des colonnes - df$new <- ..., ifelse(), et le mutate() de dplyr.

Questions fréquentes

Comment filtrer les lignes d'un data frame en R ?

Mets une condition logique dans la position des lignes entre crochets : df[df$score > 80, ]. La condition produit un vecteur TRUE/FALSE, et R garde les lignes TRUE. La virgule compte - elle sépare le filtre des lignes du filtre (vide) des colonnes. subset(df, score > 80) fait pareil en tapant moins.

Comment filtrer avec plusieurs conditions en R ?

Combine les conditions avec & (ET) et | (OU) : df[df$score > 80 & df$team == "red", ]. Utilise le simple &, pas && - la forme double ne marche que sur des valeurs uniques et provoque une erreur sur les vecteurs en R moderne.

Quelle est la différence entre subset() et le filtrage par crochets en R ?

Ils gardent les mêmes lignes, avec deux différences : subset() supprime silencieusement les lignes où la condition vaut NA (les crochets les gardent comme lignes remplies de NA), et subset() utilise l'évaluation non standard - tu écris les noms de colonnes nus, ce qui est pratique en interactif mais peu fiable dans tes propres fonctions.

Comment filtrer les lignes où une colonne correspond à une liste de valeurs ?

Utilise %in% : df[df$team %in% c("red", "blue"), ] garde les lignes dont team est l'une des valeurs listées. Ça remplace une chaîne de comparaisons == reliées par |, et contrairement à ==, ça ne renvoie jamais NA.

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER