2017-10-16 8 views
1

J'ai examiné des solutions possibles pendant un certain temps dans StackOverflow, mais je dois demander de l'aide sur celui-ci.Supprimer des lignes avec des niveaux incomplets qui ne sont pas NA

J'ai une trame de données avec la structure suivante:

df <- data.frame(A = c("A", "A", "A", "A", "B", "B", "C", "C", "C", "C", "D"), 
      B = c("F1", "F2", "F3", "F4", "F2", "F3", "F1", "F2", "F3", "F4", 
      "F4")) 

Je voudrais filtrer pour ne conserver que les lignes avec des niveaux complets, comme ci-dessous:

df_new <- data.frame(A = c("A", "A", "A", "A", "C", "C", "C", "C"), 
       B = c("F1", "F2", "F3", "F4", "F1", "F2", "F3", "F4")) 

S'il vous plaît noter que le filtrage de Col1 est soumis à la condition que Col2 doit avoir tous les niveaux lvls <- c("F1", "F2", "F3", "F4"), donc en utilisant dplyr::filter ou subset est difficile. Il s'agit d'un jeu de données long (et dynamique), donc je ne voudrais pas le faire manuellement. Merci d'avance pour votre aimable attention.

+0

Je suis désolé, dans ma question, je voulais dire: «Supprimer les lignes avec des niveaux incomplets qui ne sont pas NA». – plperez

Répondre

4

Que diriez-vous l'une de ces:

library(tidyverse) 

df %>% group_by(A) %>% 
    filter(length(unique(B)) == length(levels(B))) 

df %>% group_by(A) %>% 
    filter(n_distinct(B) == length(levels(B))) 
 A  B 
    <fctr> <fctr> 
1  A  F1 
2  A  F2 
3  A  F3 
4  A  F4 
5  C  F1 
6  C  F2 
7  C  F3 
8  C  F4 

Ou, si vous avez besoin de vous soucier de valeurs manquantes:

df %>% group_by(A) %>% 
    filter(length(unique(B[!is.na(B)])) == length(levels(B))) 

df %>% group_by(A) %>% 
    filter(n_distinct(B, na.rm=TRUE) == length(levels(B))) 
1

Voici une option avec data.table

library(data.table) 
setDT(df)[, .SD[nlevels(droplevels(B))==max(nlevels(B))], A] 
# A B 
#1: A F1 
#2: A F2 
#3: A F3 
#4: A F4 
#5: C F1 
#6: C F2 
#7: C F3 
#8: C F4