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 des lignes dans ce cadre 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 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 souhaite réellement sélectionner des lignes en fonction 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 parcourir le vecteur, extraire les lignes nécessaires et les ajouter à une nouvelle trame de données, mais j'espérais qu'il existait un moyen plus élégant.
Alors, comment puis-je filtrer/sous-définir mes données en fonction du contenu du vecteur vc
?
Jettes un coup d'oeil à ?"%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 aussi utiliser ?is.element
:
dt[is.element(dt$fct, vc),]
Semblable à ce qui précède, utilisez filter
de dplyr
:
filter(df, fct %in% vc)
Une autre option serait d'utiliser un 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
(qui est une forme améliorée d'un data.frame
) avec la colonne fct
définie comme clé .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 qu'il n'est pas encapsulé dans J()
ou .()
, vc
fonctionnera comme un index de ligne.
Une explication plus détaillée du concept de touches et du sous-ensemble se trouve dans la vignette Touches et Sous-ensemble de recherche binaire rapide .
Une alternative suggéré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 devez ajouter nomatch = 0
:
setDT(dt, key = 'fct')[J(vc), nomatch = 0]
ou:
setDT(dt)[J(vc), on=.(fct), nomatch = 0]