dplyr::filter() does not produce the expected output

Viewed 48

Please, find my data p below.

I cannot figure out why filter() does not work. I want to filter p$treatment not equal to SSTR but p$who %in% 1:3.

> table(p$who)

 1  2  3  4 
97 71 96 26 

#and 

> table(p$treatment)

   SSTR     SSA Control 
    119     131      40 

I have applied

p.ssa <- p %>% filter(!treatment=="SSTR",
                     who %in% 1:3) 

But I still get

> table(p.ssa$who)

 1  2  3  4 
53 40 78  0 

# and

> table(p.ssa$treatment)

   SSTR     SSA Control 
      0     131      40 

The expected output should be

> table(p.ssa$who)

     1  2  3  
    53 40 78  

> table(p.ssa$treatment)

   SSA Control 
   131      40 

My data

    p <- structure(list(treatment = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 1L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
    3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
    3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), .Label = c("SSTR", 
    "SSA", "Control"), class = "factor"), who = structure(c(1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 4L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 3L, 2L, 2L, 3L, 3L, 3L, 2L, 1L, 3L, 1L, 1L, 
    1L, 1L, 1L, 1L, 2L, 4L, 4L, 1L, 4L, 1L, 2L, 1L, 4L, 1L, 1L, 1L, 
    1L, 2L, 1L, 1L, 2L, 1L, 4L, 1L, 4L, 4L, 4L, 4L, 3L, 3L, 4L, 4L, 
    4L, 4L, 1L, 4L, 4L, 2L, 1L, 2L, 2L, 4L, 4L, 4L, 2L, 4L, 1L, 4L, 
    4L, 2L, 4L, 4L, 3L, 4L, 1L, 2L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 3L, 
    2L, 2L, 2L, 3L, 2L, 3L, 1L, 2L, 3L, 3L, 3L, 1L, 2L, 1L, 2L, 3L, 
    3L, 1L, 4L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 2L, 2L, 2L, 2L, 2L, 2L, 
    3L, 3L, 1L, 3L, 1L, 3L, 3L, 2L, 3L, 1L, 1L, 2L, 1L, 1L, 3L, 2L, 
    1L, 1L, 3L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 2L, 3L, 2L, 1L, 
    2L, 3L, 2L, 2L, 2L, 1L, 3L, 3L, 3L, 2L, 3L, 2L, 3L, 1L, 1L, 1L, 
    3L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 3L, 2L, 3L, 1L, 1L, 1L, 1L, 
    1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 3L, 1L, 1L, 3L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 3L, 1L, 1L, 1L, 2L, 1L, 2L, 1L, 3L, 3L, 3L, 
    3L, 3L, 2L, 1L, 1L, 1L, 1L, 2L, 2L, 1L, 1L, 1L, 2L, 3L, 2L, 2L, 
    2L, 3L, 2L, 3L, 3L, 3L, 3L, 1L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
    3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
    3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L
    ), .Label = c("1", "2", "3", "4"), class = "factor")), class = "data.frame", row.names = c(NA, 
    -290L))
2 Answers

Add droplevels to drop unused factor levels in the data.

p.ssa <- p %>% filter(treatment !="SSTR",who %in% 1:3) %>% droplevels()

table(p.ssa$who)
# 1  2  3 
#53 40 78 

table(p.ssa$treatment)
#SSA Control 
#131      40 

We can use data.table methods

library(data.table)
p.ssa <- droplevels(setDT(p)[treatment != "SSTR" & who %in% 1:3])

Or with base R

p.ssa <- droplevels(subset(p, treatment != "SSTR" & who %in% 1:3))
Related