Filter a dataset based on a grouped condition

Viewed 52

It may be an stupid question, but I can not figure out how to filter df to keep the rows in which the id match the condition of being present in all the levels of factor_A:

df = data.frame(id    = c(1,1,1,2,2,3,3), 
                factor_A = c(1,2,3,1,2,1,3))

The desired df1 would keep only the rows containing id=1, since it is present in factor_A=1,2 and 3:

     id factor_A
1     1     1
2     1     2
3     1     3
3 Answers

this should do it

library(dplyr)

df = data.frame(id    = c(1,1,1,2,2,3,3), 
                factor_A = c(1,2,3,1,2,1,3))

df %>% group_by(id) %>% 
  filter(length(unique(factor_A)) == length(unique(df$factor_A)))

I would suggest a dplyr approach. You can count the number of levels for each id and then filter. As your factor variable has 3 levels you will keep those rows with Flag equals to 3:

library(dplyr)
#Data
df = data.frame(id    = c(1,1,1,2,2,3,3), 
                factor_A = c(1,2,3,1,2,1,3))
#Create flag
df %>% group_by(id) %>%
  #Count levels
  mutate(Flag=n_distinct(factor_A)) %>%
  #Filter only rows with 3
  filter(Flag==3) %>% select(-Flag)

Output:

# A tibble: 3 x 2
# Groups:   id [1]
     id factor_A
  <dbl>    <dbl>
1     1        1
2     1        2
3     1        3

We can use base R

subset(df, id %in% names(which(!rowSums(!table(df) > 0))))
#  id factor_A
#1  1        1
#2  1        2
#3  1        3
Related