This is true, interesting! It also removes the lines where Glasgow is NA, it must have to do something how the (negated) NA is handled.
If you don't need the NAs in the age you could also remove it beforehand.
data = data.frame(
stringsAsFactors = FALSE,
region = c("Glasgow","Edinburgh","Inverness","Aberdeen",
"Glasgow","Edinburgh", "Inverness","Aberdeen",
"Glasgow","Edinburgh", "Inverness","Aberdeen",
"Glasgow", "Edinburgh","Inverness","Aberdeen",
"Glasgow", "Edinburgh","Inverness","Aberdeen",
"Glasgow", "Edinburgh","Inverness","Aberdeen",
"Glasgow", "Edinburgh","Inverness","Aberdeen",
"Glasgow", "Edinburgh","Inverness","Aberdeen"),
age = c(30L,42L,44L,NA,30L,48L,32L,42L,28L,NA,
48L,30L,42L,38L,30L,26L,46L,28L,43L,39L,20L,
35L,33L,NA,37L,43L,30L,49L,NA,27L,41L,33L),
line = 1:32
)
data %>% filter(region=="Glasgow" & age==30)
# this gives (correctly) 2 hits: line 1 and line 5
data %>% filter(!(region=="Glasgow" & age==30))
# this gives 29 - line 29 (Glasgow - NA) is missing
# using anti join
kick_out = filter(data, region=="Glasgow" & age==30)
data %>%
anti_join(kick_out)
# this gives 30, correctly without line 1 and line 5