Je voudrais savoir s'il existe un moyen de combiner l'instruction ifelse et la fonction de filtre (dans le package dplyr) pour sous-ensemble une trame de données. Considérez les données
df<-data.frame(id=c(1,2,2,2,3), A=c(3,5,4,3,9), D1=c(0,1,1,0,0), D2=c(1,0,0,1,0))
Je veux supprimer les lignes suivant D2 = 1 ou D1 = D2 = 0 pour chaque id. La sortie attendue ressemblerait à
df<-data.frame(id=c(1,1,1,2,2,2,2,3,3), A=c(3,6,2,5,4,3,8,9,8), D1=c(0,0,0,1,1,0,0,0,0), D2=c(1,0,0,0,0,1,1,0,1))
J'ai abordé cela par plusieurs tentatives en utilisant group_by et la fonction de filtre mais il semble que des instructions conditionnelles soient nécessaires mais je trouve difficile de combiner ceux-ci avec la fonction de filtre. J'ai rencontré plusieurs questions / réponses sur les données de sous-ensembles (par exemple, Comment sous-regrouper les données en filtrant et regroupant efficacement dans R ) mais celles-ci ne répondent pas à ma question. J'apprécie grandement toute aide à ce sujet.
3 Réponses :
Dans dplyr
, vous pouvez trouver le premier index où la condition est remplie et sélectionner les lignes qui se produisent avant que la condition ne soit satisfaite pour chaque groupe.
df %>% group_by(id) %>% slice({ inds <- which(D1 == 0 & D2 == 0 | D2 == 1)[1] if(!is.na(inds)) -((inds + 1):n()) else seq_len(n())})
Ce qui précède fonctionne en supposant qu'au moins une ligne dans chaque groupe satisfait à la condition. Un cas général, où il peut y avoir des instances où aucune des lignes ne satisfait la condition et que nous voulons sélectionner toutes les lignes du groupe que nous pouvons utiliser:
library(dplyr) df %>% group_by(id) %>% filter(row_number() <= which(D1 == 0 & D2 == 0 | D2 == 1)[1]) # id A D1 D2 # <dbl> <dbl> <dbl> <dbl> #1 1 3 0 1 #2 2 5 1 0 #3 2 4 1 0 #4 2 3 0 1 #5 3 9 0 0
Il ne semble pas que vous ayez besoin d'utiliser dplyr
ici (sauf si je manque quelque chose). Essayez ceci:
df<-data.frame(id=c(1,1,1,2,2,2,2,3,3), A=c(3,6,2,5,4,3,8,9,8), D1=c(0,0,0,1,1,0,0,0,0), D2=c(1,0,0,0,0,1,1,0,1)) del = c() for (i in 1:nrow(df)){ if (df$D2[i] == 1 | (df$D1[i] ==0 & df$D2[i] == 0)){ del = c(del, i) } } df = df[del,]
Pure dplyr
:
df %>% group_by(id) %>% filter(row_number() == n() | rev(cumany(rev(!(D2 == 1 | (D1 == D2 & D2 == 0)))))) # # A tibble: 5 x 4 # # Groups: id [3] # id A D1 D2 # <dbl> <dbl> <dbl> <dbl> # 1 1 2 0 0 # 2 2 5 1 0 # 3 2 4 1 0 # 4 2 8 0 1 # 5 3 8 0 1
L'une des réponses répond-elle à votre question, TRichard? Si tel est le cas, veuillez en accepter un. Merci!