Filtrage d'une trame de données

12

Toujours en train d'apprendre les fonctions de base dans R, la fonction de sous-ensemble semble filtrer uniquement une condition basée sur une seule colonne avec ou sans plusieurs conditions?

Comment filtrer facilement les données d'une trame de données?

  1. lorsque plusieurs conditions vous sont proposées

  2. Lorsque la condition doit être appliquée dans les colonnes disponibles.

Exemple: étant donné un bloc de données contenant

name    D1      D2     D3      D4
julius  "A"     "A"    "B"     "B"
cate    "D"     "E"     "A"     "C"
karo    "A"     "D"     "C"     "E"

dis que je veux filtrer cette trame de données afin que seuls les noms où l'un des D1 à D4 soit un «E», alors je devrais avoir,

name    D1      D2     D3      D4
cate    "D"     "E"     "A"     "C"
karo    "A"     "D"     "C"     "E"

Disons que le D1 peut être une grande liste de colonnes, comment ou quelle est l'approche recommandée pour effectuer ce filtre? Je vous remercie

eastafri
la source

Réponses:

26

Si vous souhaitez combiner plusieurs filtres dans la fonction de sous-ensemble , utilisez des opérateurs logiques:

 subset(data, D1 == "E" | D2 == "E")

sélectionnera les lignes pour lesquelles la colonne D1 ou la colonne D2 a la valeur "E". Consultez les pages d'aide pour les opérateurs logiques disponibles:

 > ?"|"

Pour votre deuxième question, vous devez filtrer les lignes. Ceci peut être réalisé de la manière suivante

 collist <- c("D1","D2","D3","D4")
 sel <- apply(data[,collist],1,function(row) "E" %in% row)
 data[sel,]

Le premier argument à appliquer fournit les colonnes sur lesquelles nous devons filtrer. Le deuxième argument est 1, ce qui signifie que nous parcourons les lignes de données en boucle. Le troisième argument est une fonction d'une ligne sans nom qui renvoie VRAI si "E" est présent dans la ligne et FAUX si le "E" n'est pas présent.

Le résultat de la fonction d'application sera un vecteur logique sel , qui a la même longueur que le nombre de lignes dans les données. Nous utilisons ensuite ce vecteur pour sélectionner les lignes nécessaires.

Mise à jour

La même chose peut être obtenue avec grep:

sel <- apply(data[,collist],1,function(row) length(grep("E",row))>0)

dans R grep avec des arguments par défaut renvoie le nombre d'éléments dans le vecteur fourni qui ont le motif correspondant.

mpiktas
la source
2
une autre fonction utile est any. Par exemple, si vous voulez vérifier qu'au moins un élément d'un vecteur est, = 10vous pouvez écrire ( any(v==10)).
nico
@nico oui, mais 10% en v% a 9 caractères et variant avec tout 10 :). Bien que pour les vecteurs numériques, il est préférable d'utiliser l'égalité, car R est intelligent et si vos données sont des entiers mélangés à des nombres réels, il reconnaîtra correctement que vous avez 10 dans votre ensemble de données.
mpiktas
qu'en est-il du cas de l'expression régulière? en supposant que vous ne voulez pas travailler avec une correspondance exacte? Ont-ils quelque chose de proche de ~ = comme dans d'autres langues? ce qui est le plus proche de cette expression dans R
eastafri
@Biorelated Voir grepet agrep, et la documentation connexe sur POSIX 1003.2 ou regex compatible Perl.
chl
@Biorelated, j'ai mis à jour la réponse avec l'exemple de grep.
mpiktas