1

Here is a data frame:

 df <- data.frame(letter = rep(c("a","b","c","d"), each = 4), number = c(2,1,5,3,9,4,2,4,3,11,1,2,1,1,5,6))

I know how to remove a rows based on an observation:

rmv <- with(df, number > 8) # finds observations greater than 8
new.df<- df[!rmv, ] # removes observations

However, I want to remove all inputs for each letter group (i.e., all the 'b' and 'c' inputs) if there are any observations greater than 8. Ideal output would be:

      letter number
 1       a      2
 2       a      1
 3       a      5
 4       a      3
 13      d      1
 14      d      1
 15      d      5
 16      d      6

How would I accomplish this?

B C
  • 318
  • 3
  • 16

1 Answers1

1

We can use any, negate (!) after doing a group by 'letter'

library(dplyr)
df %>% 
   group_by(letter) %>% 
   filter(!any(number > 8))

Or do the reverse with all

df %>%
   group_by(letter) %>%
   filter(all(number <= 8))

In base R, this can be done with ave

df[with(df, ave(number <= 8, letter, FUN = all)),]
akrun
  • 874,273
  • 37
  • 540
  • 662