Reputation: 67
I would like to filter by a level i.e for level D>2 and B>7 but retain the other levels in a data frame. How can achieve this using dplyr
?
Here is a minimal example.
df <- data.frame(x = c("A","A","A","B","B","B","C","C","D","D","D"),
y = c(10,1,5,2,7,9,8,3,2,3,5) )
I tried the following but this is not what I want.
df %>%
dplyr::filter(x=="D" & y>2 | x=="B" & y>7)
I expect the output to be:
x y
A 10
A 1
A 5
B 9
C 8
C 3
D 3
D 5
Upvotes: 2
Views: 368
Reputation: 76621
Just include a condition to get the rows where x
is not one of those levels.
df %>%
filter((x == "D" & y > 2) |
(x == "B" & y > 7) |
(!x %in% c("B", "D")))
# x y
#1 A 10
#2 A 1
#3 A 5
#4 B 9
#5 C 8
#6 C 3
#7 D 3
#8 D 5
Upvotes: 2
Reputation: 6441
Just reverse the logic of your filtering.
df %>%
dplyr::filter(!(x =="D" & y<=2 | x=="B" & y<=7))
x y
1 A 10
2 A 1
3 A 5
4 B 9
5 C 8
6 C 3
7 D 3
8 D 5
Upvotes: 2
Reputation: 389175
You could filter
"B"
and "D"
levels separately and bind the rows.
library(dplyr)
bind_rows(df %>% filter(!x %in% c("B", "D")),
df %>% filter(x =="D" & y>2 | x=="B" & y>7))
# x y
#1 A 10
#2 A 1
#3 A 5
#4 C 8
#5 C 3
#6 B 9
#7 D 3
#8 D 5
In base R, that would be
rbind(subset(df, !x %in% c("B", "D")), subset(df, x=="D" & y>2 | x=="B" & y>7))
Upvotes: 2