Filtrer les valeurs multiples sur une colonne de chaîne en dplyr

j'ai un data.frame avec des données de caractère dans une des colonnes. Je voudrais filtrer plusieurs options dans le data.frame dans la même colonne. Est-il un moyen facile de faire ce que je suis absent?

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)

j'ai cette erreur:

longer object length is not a multiple of shorter object length
46
demandé sur smci 2014-09-03 18:51:24

3 réponses

Vous avez besoin d' %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

permet De comprendre pourquoi ce qui se passe ici:

dat$name == target
# [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE

en gros, nous recyclons les deux longueurs target vecteur quatre fois pour correspondre à la longueur de dat$name. En d'autres termes, nous sommes en train de faire:

 Lynn == Tom
  Tom == Lynn
Chris == Tom
 Lisa == Lynn
 ... continue repeating Tom and Lynn until end of data frame

dans ce cas nous n'avons pas d'erreur parce que je soupçonne que votre base de données a en fait un nombre différent de lignes qui ne permettent pas le recyclage, mais le échantillon que vous fournissez (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. Fondamentalement, la déclaration dat$name == target équivaut à dire:

retour TRUE pour chaque valeur impaire qui est égal à "Tom" ou tous la même valeur qui est égale à "Lynn".

il se trouve que la dernière valeur dans votre base de données d'échantillon est égale à "Lynn", d'où celui TRUE ci-dessus.

Pour le contraste, dat$name %in% target dit:

pour chaque valeur de dat$name, vérifiez qu'il existe dans target.

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 de la mauvaise utilisation ou l'utilisation de ==.

126
répondu BrodieG 2014-09-03 15:01:36

base package:

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

en utilisant sqldf:

library(sqldf)
# Two alternatives:
sqldf('SELECT *
      FROM df 
      WHERE name = "Tom" OR name = "Lynn"')
sqldf('SELECT *
      FROM df 
      WHERE name IN ("Tom", "Lynn")')
7
répondu mpalanco 2015-06-24 10:10:34

cela peut être réalisé en utilisant le paquet dplyr, qui est disponible dans CRAN. La façon simple d'obtenir ceci:

  1. Installer dplyr paquet.

  2. 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 cadre de données en utilisant deux fonctions différentes de ce paquet:

filter: le premier argument est le data frame; le second argument est la condition par laquelle nous voulez incorporée dans un jeu partiel. Le résultat est l'ensemble de la base de données avec seulement les lignes que nous voulions. select: le premier argument est le data frame; le second argument est le nom des colonnes que nous voulons sélectionner à partir de celui-ci. Nous n'avons pas à utiliser les noms de fonction (), et nous n'avons même pas utiliser des guillemets. Nous énumérons simplement les noms de colonne comme des objets.

6
répondu AutomationNerd 2017-10-21 19:49:04