Sélectionner des lignes dans un bloc de données en fonction des valeurs d’un vecteur

J’ai des données similaires à ceci:

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 souhaite sélectionner les lignes de ce bloc de données en fonction des valeurs de la variable fct . Par exemple, si je souhaite sélectionner des lignes contenant “a” ou “c”, je peux le faire:

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

qui cède

 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 souhaite en fait sélectionner des lignes en fonction des valeurs d’un vecteur tel que

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

J’ai donc essayé

 dt[dt$fct == vc, ] 

mais bien sûr ça ne marche pas. Je sais que je pourrais coder quelque chose pour parcourir le vecteur, extraire les lignes nécessaires et les append à un nouveau dataframe, mais j’espérais qu’il y avait une manière plus élégante.

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

Regardez ?"%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),] 

Similaire à ci-dessus, en utilisant le filter de dplyr :

 filter(df, fct %in% vc) 

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

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

qui se traduit par:

  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 

Qu’est-ce que cela fait:

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

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

Une explication plus détaillée du concept de clés et de sous-ensemble peut être trouvée dans le sous-ensemble de clés de vignette et de recherche binary rapide .

Une alternative proposée par @Frank dans les commentaires:

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

Lorsque vc contient des valeurs qui ne sont pas présentes dans dt , vous devrez append nomatch = 0 :

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

ou:

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