Filtrer les lignes en R : subset() base R & filter() dplyr

Conserver les lignes qui remplissent une condition — crochets base R et subset(), et filter() de dplyr

Filtrez les lignes d’un data frame en R avec la base R df[df$x > 5, ] et subset(), ou filter() de dplyr. Filtrez selon une ou plusieurs conditions (&, |, %in%, between()), conservez les n premières lignes avec head()/slice(), et gérez la différence de NA entre [ et filter() — les deux approches, même résultat.

Date de publication

26 juin 2026

Modifié

7 juillet 2026

AstucePoints clés
  • base R : df[df$x > 5, ] conserve les lignes où la condition est TRUE ; subset(df, x > 5) en est la forme plus lisible.
  • dplyr : filter(df, x > 5) fait la même chose ; combinez les conditions avec & / |, ou simplement des virgules (= ET).
  • Appartenance & intervalles : x %in% c("a", "b") et between(x, lo, hi) conservent les lignes correspondant à un ensemble ou à un intervalle.
  • n premières lignes : head(df, 5), df[1:5, ], ou slice(df, 1:5) / slice_head(df, n = 5) de dplyr.
  • Piège des NA : la base [ conserve une ligne fantôme entièrement NA lorsque la condition vaut NA ; subset() et filter() la suppriment. Utilisez filter() ou which() pour éviter le problème.

Introduction

La plupart des analyses commencent par conserver les lignes qui comptent — les patients de plus de 60 ans, les commandes du dernier trimestre, l’espèce qui vous intéresse. C’est le filtrage (ou la sélection) de lignes selon une condition.

Cette leçon couvre les deux approches que vous rencontrerez dans du code réel :

  • base R — indexez avec [ à l’aide d’une condition logique, ou utilisez subset() pour une lecture plus claire ; aucun package nécessaire.
  • dplyr filter() — la valeur par défaut moderne, avec des aides comme %in% et between().

Elles donnent les mêmes lignes, vous pouvez donc lire n’importe quel code et choisir celle que vous préférez. Il y a une vraie différence — la manière dont chacune gère les valeurs manquantes — et nous l’abordons directement. Nous utilisons le jeu de données intégré iris :

head(iris)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

Filtrer selon une condition

base R — df[condition, ]

Le crochet [ prend les lignes avant la virgule et les colonnes après. Une condition logique dans l’emplacement des lignes conserve les lignes où elle vaut TRUE. Ici, nous conservons les fleurs dont le sépale dépasse 7 :

big <- iris[iris$Sepal.Length > 7, ]
head(big)
    Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
103          7.1         3.0          5.9         2.1 virginica
106          7.6         3.0          6.6         2.1 virginica
108          7.3         2.9          6.3         1.8 virginica
110          7.2         3.6          6.1         2.5 virginica
118          7.7         3.8          6.7         2.2 virginica
119          7.7         2.6          6.9         2.3 virginica

Notez la virgule finale — iris[condition, ] conserve toutes les colonnes. La condition iris$Sepal.Length > 7 est un vecteur de TRUE/FALSE, un par ligne.

subset() exprime la même chose sans répéter le nom du data frame — vous écrivez la colonne sans préfixe :

big <- subset(iris, Sepal.Length > 7)
head(big)
    Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
103          7.1         3.0          5.9         2.1 virginica
106          7.6         3.0          6.6         2.1 virginica
108          7.3         2.9          6.3         1.8 virginica
110          7.2         3.6          6.1         2.5 virginica
118          7.7         3.8          6.7         2.2 virginica
119          7.7         2.6          6.9         2.3 virginica

subset(df, condition) est la forme base R lisible : pas de df$, pas de virgule finale à oublier.

dplyr — filter(df, condition)

filter() se lit de la même manière que subset() :

library(dplyr)
big <- filter(iris, Sepal.Length > 7)
head(big)
  Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
1          7.1         3.0          5.9         2.1 virginica
2          7.6         3.0          6.6         2.1 virginica
3          7.3         2.9          6.3         1.8 virginica
4          7.2         3.6          6.1         2.5 virginica
5          7.7         3.8          6.7         2.2 virginica
6          7.7         2.6          6.9         2.3 virginica

Les trois renvoient les mêmes lignesfilter() et subset() sont les formes claires ; le [ brut montre ce qu’elles font en coulisses.

Combiner plusieurs conditions

Utilisez & pour ET (toutes doivent être vraies) et | pour OU (au moins une peut être vraie). Ici : sépales longs et espèce virginica.

base R

sel <- subset(iris, Sepal.Length > 6.5 & Species == "virginica")
head(sel)
    Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
103          7.1         3.0          5.9         2.1 virginica
106          7.6         3.0          6.6         2.1 virginica
108          7.3         2.9          6.3         1.8 virginica
109          6.7         2.5          5.8         1.8 virginica
110          7.2         3.6          6.1         2.5 virginica
113          6.8         3.0          5.5         2.1 virginica

dplyr

Dans filter(), séparer les conditions par une virgule revient au même que & — un raccourci courant :

library(dplyr)
sel <- filter(iris, Sepal.Length > 6.5, Species == "virginica")
head(sel)
  Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
1          7.1         3.0          5.9         2.1 virginica
2          7.6         3.0          6.6         2.1 virginica
3          7.3         2.9          6.3         1.8 virginica
4          6.7         2.5          5.8         1.8 virginica
5          7.2         3.6          6.1         2.5 virginica
6          6.8         3.0          5.5         2.1 virginica

Pour le OU, utilisez | dans les deux approches : subset(iris, Species == "setosa" | Sepal.Length > 7).

Correspondre à un ensemble de valeurs : %in%

Pour conserver les lignes où une colonne est l’une de plusieurs valeurs, n’enchaînez pas == avec |. Utilisez %in% :

two <- subset(iris, Species %in% c("setosa", "virginica"))
table(two$Species)

    setosa versicolor  virginica 
        50          0         50 

Cela se lit de la même façon en dplyr :

library(dplyr)
two <- filter(iris, Species %in% c("setosa", "virginica"))
table(two$Species)

    setosa versicolor  virginica 
        50          0         50 

%in% est en base R, il fonctionne donc à l’identique dans les deux approches — la manière la plus propre de filtrer par rapport à une liste.

Correspondre à un intervalle numérique : between()

Pour « entre deux nombres », le between() de dplyr est plus clair que deux comparaisons :

library(dplyr)
mid <- filter(iris, between(Sepal.Length, 5, 6))
nrow(mid)
[1] 67

L’équivalent en base R est deux comparaisons jointes par & :

mid <- subset(iris, Sepal.Length >= 5 & Sepal.Length <= 6)
nrow(mid)
[1] 67

Même décompte — between() est le raccourci lisible. Notez qu’il est inclusif des deux bornes.

Conserver les n premières lignes

Lorsque vous voulez des lignes par position, et non par condition — les premières, une tranche précise — utilisez l’indexation par position.

# first 5 rows, base R
head(iris, 5)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa

iris[1:5, ] fait la même chose par index explicite. La famille slice() de dplyr est l’équivalent tidy :

library(dplyr)
slice(iris, 1:5)            # rows 1 through 5
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa

slice_head(iris, n = 5) conserve les 5 premières et slice_max(iris, Sepal.Length, n = 3) conserve les 3 plus grandes — pratique quand « premières » signifie « en tête selon une valeur » :

library(dplyr)
slice_max(iris, Sepal.Length, n = 3)
  Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
1          7.9         3.8          6.4         2.0 virginica
2          7.7         3.8          6.7         2.2 virginica
3          7.7         2.6          6.9         2.3 virginica
4          7.7         2.8          6.7         2.0 virginica
5          7.7         3.0          6.1         2.3 virginica

Le piège des NA — la base [ face à filter()

C’est la seule vraie différence, et elle piège les gens. Lorsqu’une condition s’évalue à NA (parce que la valeur de la colonne est manquante), la base [ conserve une ligne fantôme entièrement NA, tandis que subset() et filter() la suppriment discrètement.

# a small frame with a missing value
df <- data.frame(id = 1:4, x = c(10, NA, 30, 5))

# base [: the NA condition leaks a phantom all-NA row
df[df$x > 8, ]
   id  x
1   1 10
NA NA NA
3   3 30

Cette ligne NA NA n’est presque jamais ce que vous voulez. subset() et filter() la gèrent correctement :

library(dplyr)
subset(df, x > 8)     # base, but NA-safe
  id  x
1  1 10
3  3 30
filter(df, x > 8)     # dplyr, NA-safe
  id  x
1  1 10
2  3 30

Si vous devez utiliser le [ brut, enveloppez la condition dans which() — il renvoie uniquement les positions TRUE et ignore les NA :

df[which(df$x > 8), ]
  id  x
1  1 10
3  3 30

Règle générale : préférez filter() ou subset() ; si vous recourez au [ brut sur une colonne susceptible de contenir des NA, utilisez which().

Essayez en direct

Les blocs ci-dessus ont été exécutés au moment de la génération. Modifiez celui-ci et appuyez sur Run pour filtrer des lignes par vous-même — il s’exécute dans votre navigateur via webR (sans installation).

🟢 Avec un agent IA

Le filtrage réel devient vite désordonné — une plage de dates, une liste d’identifiants, des valeurs manquantes qui suppriment discrètement des lignes que vous vouliez garder. Décrivez les lignes que vous voulez et demandez à Prova « filtre pour virginica avec une longueur de sépale supérieure à 6.5, et dis-moi si des lignes avaient des NA dans cette colonne » ; elle écrit l’appel à filter(), et comme le runtime est juste là, vous l’exécutez pour confirmer que le nombre de lignes correspond à ce que vous attendiez sur vos données — le piège des NA est exactement là où un copier-coller à l’aveugle dérape. Demandez à Prova →

Vous travaillez en Python ? Un guide de filtrage de lignes pandas (masques booléens, .query(), .isin(), .between()) arrive dans la série Python.

Problèmes courants

subset()/filter() renvoie zéro ligne alors que vous en attendiez. Le plus souvent, une faute de frappe dans un niveau de facteur ou une différence de casse — Species == "Virginica" ne correspond à rien parce que le niveau est en minuscules "virginica". Vérifiez les valeurs exactes avec unique(df$Species) ou levels(df$Species).

La base [ renvoie des lignes entièrement NA superflues. La condition a produit NA sur les lignes où la colonne est manquante, et [ les conserve sous forme de lignes vides (voir la section NA ci-dessus). Passez à filter() / subset(), ou enveloppez la condition dans which().

filter() affiche « object not found ». Vous avez mis un nom de colonne entre guillemets — filter(iris, "Species" == "setosa") compare deux chaînes, jamais la colonne. dplyr prend des noms de colonnes sans guillemets : filter(iris, Species == "setosa"). (La base subset() fonctionne pareil — subset(iris, Species == "setosa"), sans guillemets.)

Questions fréquentes

Conservez les lignes où une condition vaut TRUE. Base R : df[df$x > 5, ] (notez la virgule finale) ou la forme plus lisible subset(df, x > 5). dplyr : filter(df, x > 5). Les trois renvoient les mêmes lignes.

Elles conservent les mêmes lignes. subset() est en base R (aucun package) ; filter() est dans dplyr. Les deux prennent des noms de colonnes sans guillemets et suppriment les lignes où la condition vaut NA. La forme brute df[cond, ] est la plus rapide à taper mais conserve des lignes fantômes entièrement NA lorsque la condition est manquante, donc subset()/filter() sont plus sûres.

Joignez les conditions avec & (ET) ou | (OU) : subset(df, x > 5 & y == "a"). Dans filter() de dplyr, une virgule entre conditions signifie aussi ET : filter(df, x > 5, y == "a"). Pour correspondre à un ensemble de valeurs, utilisez %in% : filter(df, group %in% c("a", "b")).

Indexez par position : df[c(1, 3, 5), ] conserve les lignes 1, 3 et 5 ; df[1:10, ] conserve les dix premières ; head(df, 10) est le raccourci lisible. En dplyr, slice(df, 1:10) ou slice_head(df, n = 10) font la même chose.

La base df[df$x > 5, ] conserve une ligne vide entièrement NA dès que x est manquant, parce que la comparaison renvoie NA (et non FALSE). Utilisez subset() ou filter() de dplyr, qui suppriment ces lignes automatiquement, ou enveloppez la condition dans which() : df[which(df$x > 5), ].

Testez vos connaissances

À partir d’iris, conservez les lignes où Species est setosa ou versicolor et Sepal.Width est supérieure à 3. D’abord avec subset() en base R, puis avec filter() de dplyr — et confirmez que les deux renvoient le même nombre de lignes.

# base R: subset(iris, Species %in% c("setosa", "versicolor") & Sepal.Width > 3)
# dplyr:  filter(iris, Species %in% c("setosa", "versicolor"), Sepal.Width > 3)
library(dplyr) base_way <- subset(iris, Species %in% c("setosa", "versicolor") & Sepal.Width > 3) dplyr_way <- filter(iris, Species %in% c("setosa", "versicolor"), Sepal.Width > 3) nrow(base_way) == nrow(dplyr_way) # TRUE
library(dplyr)

base_way <- subset(iris, Species %in% c("setosa", "versicolor") & Sepal.Width > 3)

dplyr_way <- filter(iris, Species %in% c("setosa", "versicolor"), Sepal.Width > 3)

nrow(base_way) == nrow(dplyr_way)  # TRUE

df possède une colonne numérique x. Quel appel conserve les lignes où x vaut l’une des valeurs 2, 4 ou 6 ?

A. filter(df, x == 2 | 4 | 6) B. filter(df, x %in% c(2, 4, 6)) C. filter(df, x == c(2, 4, 6))

Afficher la réponse

B. %in% teste l’appartenance à un ensemble — exactement ce que vous voulez. A est un bug classique : x == 2 | 4 | 6 s’interprète comme (x == 2) | 4 | 6, et les 4/6 nus sont toujours vrais, donc l’appel conserve toutes les lignes. C recycle le vecteur et ne fait correspondre qu’une ligne sur trois par position. Utilisez toujours %in% pour « l’une de ces valeurs ».

Conclusion

Le filtrage de lignes se résume à deux outils équivalents : df[cond, ] / subset(df, cond) en base R, ou filter(df, cond) de dplyr. Combinez les conditions avec & / | (ou une virgule dans filter()), correspondez à un ensemble avec %in%, à un intervalle avec between(), et prenez des lignes par position avec head() / slice(). La seule différence qui compte concerne les valeurs manquantes — subset() et filter() suppriment proprement les conditions NA, le [ brut non, alors recourez-y (ou à which()) dès qu’une colonne peut être manquante.

Leçons connexes

Cette page vous a-t-elle été utile ?

Prouvez que vous savez le faire. Maîtrisez toute la série Manipulation de données en R et Python — suivez votre parcours, construisez des projets et obtenez un certificat.

Commencer gratuitement →

Passez à Pro — Prova illimité sur vos propres données et un certificat vérifiable qui atteste la compétence.

dès 15 $/mois facturé annuellement

Passer à Pro →

✓ Vous êtes Pro — continuez. The runtime is the judge.

Recevez les nouvelles leçons R & Python par e-mail

Pratique, reproductible, sans spam. Désinscription à tout moment.

Double opt-in. Nous ne partageons jamais votre e-mail.

Partager cette pageXLinkedInRedditHN
Note

Cette leçon est reproductible : chaque résultat de cette page a été produit par le code affiché — modifiez n’importe quel bloc et appuyez sur Run pour le reproduire dans votre navigateur. The runtime is the judge.

Réutilisation

Citation

BibTeX
@online{2026,
  author = {},
  title = {Filtrer les lignes en R : subset() base R \& filter() dplyr},
  date = {2026-06-26},
  url = {https://www.datanovia.com/learn/programming/data-wrangling/subset-rows-in-r},
  langid = {fr}
}
Veuillez citer ce travail comme suit :
“Filtrer les lignes en R : subset() base R & filter() dplyr.” 2026. June 26. https://www.datanovia.com/learn/programming/data-wrangling/subset-rows-in-r.