J'ai un data.frame
avec des données de caractères dans l'une des colonnes. Je voudrais filtrer plusieurs options dans le data.frame
de la même colonne. Y at-il un moyen facile de faire cela qui me manque?
Exemple:data.frame
name = dat
days name
88 Lynn
11 Tom
2 Chris
5 Lisa
22 Kyla
1 Tom
222 Lynn
2 Lynn
J'aimerais filtrer Tom
et Lynn
par exemple.
Quand je fais:
target <- c("Tom", "Lynn")
filt <- filter(dat, name == target)
Je reçois cette erreur:
longer object length is not a multiple of shorter object length
Vous avez besoin de %in%
au lieu de ==
:
library(dplyr)
target <- c("Tom", "Lynn")
filter(dat, name %in% target) # equivalently, dat %>% filter(name %in% target)
Produit
days name
1 88 Lynn
2 11 Tom
3 1 Tom
4 222 Lynn
5 2 Lynn
Pour comprendre pourquoi, considérons ce qui se passe ici:
dat$name == target
# [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE
Fondamentalement, nous recyclons quatre fois le vecteur target
length afin de faire correspondre la longueur de dat$name
. En d'autres termes, nous faisons:
Lynn == Tom
Tom == Lynn
Chris == Tom
Lisa == Lynn
... continue repeating Tom and Lynn until end of data frame
Dans ce cas, nous n'obtenons pas d'erreur, car je soupçonne que votre trame de données comporte en fait un nombre différent de lignes qui ne permettent pas le recyclage, mais l'échantillon que vous fournissez en contient (8 lignes). Si l'échantillon avait eu un nombre impair de lignes, j'aurais eu la même erreur que vous. Mais même lorsque le recyclage fonctionne, ce n’est clairement pas ce que vous voulez. En gros, l'instruction dat$name == target
équivaut à dire:
return
TRUE
pour chaque valeur impaire égale à "Tom" ou chaque valeur paire égale à "Lynn".
Il se trouve que la dernière valeur de votre trame de données exemple est égale et égale à "Lynn", d'où celle TRUE
ci-dessus.
Par contraste, dat$name %in% target
dit:
pour chaque valeur dans
dat$name
, vérifiez qu'elle existe danstarget
.
Très différent. Voici le résultat:
[1] TRUE TRUE FALSE FALSE FALSE TRUE TRUE TRUE
Notez que votre problème n'a rien à voir avec dplyr
, juste à la mauvaise utilisation de ==
.
Ceci peut être réalisé en utilisant le package dplyr, disponible dans CRAN. Le moyen simple d'y parvenir:
Installez le paquet dplyr
.
library(dplyr) df<- select(filter(dat,name=='tom'| name=='Lynn',c('days','name))
Explication:
Donc, une fois que nous avons téléchargé dplyr, nous créons un nouveau bloc de données en utilisant deux fonctions différentes de ce paquet:
filtre: le premier argument est le cadre de données; le deuxième argument est la condition par laquelle nous voulons le sous-définir. Le résultat est l'ensemble du cadre de données avec uniquement les lignes que nous souhaitions. select: le premier argument est le cadre de données; le deuxième argument est le nom des colonnes que nous voulons en sélectionner. Nous n’avons pas besoin d’utiliser la fonction names () et nous n’avons même pas besoin de guillemets. Nous listons simplement les noms de colonnes sous forme d'objets.
Utilisation du package base
:
df <- data.frame(days = c(88, 11, 2, 5, 22, 1, 222, 2), name = c("Lynn", "Tom", "Chris", "Lisa", "Kyla", "Tom", "Lynn", "Lynn"))
# Three lines
target <- c("Tom", "Lynn")
index <- df$name %in% target
df[index, ]
# One line
df[df$name %in% c("Tom", "Lynn"), ]
Sortie:
days name
1 88 Lynn
2 11 Tom
6 1 Tom
7 222 Lynn
8 2 Lynn
Utiliser sqldf
:
library(sqldf)
# Two alternatives:
sqldf('SELECT *
FROM df
WHERE name = "Tom" OR name = "Lynn"')
sqldf('SELECT *
FROM df
WHERE name IN ("Tom", "Lynn")')