92 votes

Sélectionnez les lignes d'un cadre de données en fonction des valeurs d'un vecteur.

J'ai des données similaires à celles-ci :

dt <- structure(list(fct = structure(c(1L, 2L, 3L, 4L, 3L, 4L, 1L, 2L, 3L, 1L, 2L, 3L, 2L, 3L, 4L), .Label = c("a", "b", "c", "d"), class = "factor"), X = c(2L, 4L, 3L, 2L, 5L, 4L, 7L, 2L, 9L, 1L, 4L, 2L, 5L, 4L, 2L)), .Names = c("fct", "X"), class = "data.frame", row.names = c(NA, -15L))

Je veux sélectionner des lignes de ce cadre de données en fonction des valeurs de l'élément fct variable. Par exemple, si je souhaite sélectionner les lignes contenant soit "a" soit "c", je peux procéder comme suit :

dt[dt$fct == 'a' | dt$fct == 'c', ]

ce qui donne

1    a 2
3    c 3
5    c 5
7    a 7
9    c 9
10   a 1
12   c 2
14   c 4

comme prévu. Mais mes données réelles sont plus complexes et je veux en fait sélectionner des lignes sur la base des valeurs d'un vecteur tel que

vc <- c('a', 'c')

Alors j'ai essayé

dt[dt$fct == vc, ]

mais bien sûr, ça ne marche pas. Je sais que je pourrais coder quelque chose pour boucler le vecteur, en extraire les lignes nécessaires et les ajouter à un nouveau cadre de données, mais j'espérais qu'il existait une méthode plus élégante.

Alors, comment puis-je filtrer/sous-former mes données en fonction du contenu du vecteur ? vc ?

157voto

rengis Points 4733

Jetez un coup d'œil à ?"%in%" .

dt[dt$fct %in% vc,]
   fct X
1    a 2
3    c 3
5    c 5
7    a 7
9    c 9
10   a 1
12   c 2
14   c 4

Vous pouvez également utiliser ?is.element :

dt[is.element(dt$fct, vc),]

35voto

Andrew Haynes Points 1649

Comme ci-dessus, en utilisant filter de dplyr :

filter(df, fct %in% vc)

15voto

Jaap Points 3814

Une autre option serait d'utiliser une clé data.table :

library(data.table)
setDT(dt, key = 'fct')[J(vc)]  # or: setDT(dt, key = 'fct')[.(vc)]

ce qui entraîne :

   fct X
1:   a 2
2:   a 7
3:   a 1
4:   c 3
5:   c 5
6:   c 9
7:   c 2
8:   c 4

Ce que ça fait :

  • setDT(dt, key = 'fct') transforme le data.frame à un data.table (qui est une forme améliorée d'un data.frame ) avec le fct colonne définie comme clé.
  • Ensuite, vous pouvez simplement faire un sous-ensemble avec l'option vc vecteur avec [J(vc)] .

NOTE : lorsque la clé est un facteur/une variable de caractère, vous pouvez également utiliser setDT(dt, key = 'fct')[vc] mais cela ne fonctionnera pas lorsque vc est un vecteur numérique. Lorsque vc est un vecteur numérique et n'est pas enveloppée dans J() o .() , vc fonctionnera comme un rowindex.

Une explication plus détaillée du concept de clés et le sous-ensemble peuvent être trouvés dans la vignette Sous-ensemble basé sur la recherche binaire rapide et clé .

Une alternative telle que suggérée par @Frank dans les commentaires :

setDT(dt)[J(vc), on=.(fct)]

En vc contient des valeurs qui ne sont pas présentes dans dt vous devrez ajouter nomatch = 0 :

setDT(dt, key = 'fct')[J(vc), nomatch = 0]

ou :

setDT(dt)[J(vc), on=.(fct), nomatch = 0]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X