18

What is the best way to filter rows from data frame when the values to be deleted are stored in a vector? In my case I have a column with dates and want to remove several dates.

I know how to delete rows corresponding to one day, using !=, e.g.:

m[m$date != "01/31/11", ]

To remove several dates, specified in a vector, I tried:

m[m$date != c("01/31/11", "01/30/11"), ]

However, this generates a warning message:

Warning message:
In `!=.default`(m$date, c("01/31/11", "01/30/11")) :
longer object length is not a multiple of shorter object length
Calls: [ ... [.data.frame -> Ops.dates -> NextMethod -> Ops.times -> NextMethod

What is the correct way to apply a filter based on multiple values?

4 Answers 4

40

nzcoops is spot on with his suggestion. I posed this question in the R Chat a while back and Paul Teetor suggested defining a new function:

`%notin%` <- function(x,y) !(x %in% y) 

Which can then be used as follows:

foo <- letters[1:6]

> foo[foo %notin% c("a", "c", "e")]
[1] "b" "d" "f"

Needless to say, this little gem is now in my R profile and gets used quite often.

Sign up to request clarification or add additional context in comments.

4 Comments

Nice. I always find it breaks my concentration when I have to type something like !(x %in% y)... great tip.
I don't think dplyr can handle this, e.g., filter(df, foo %notin% c("a", "c", "e"))
It was just a comment! I was trying to use %noin% in a filter call and it didn't work, non-suprisingly.
@MattO'Brien, I posted an equivalent using anti_join below . . .
14

I think for that you want:

m[!m$date %in% c("01/31/11","01/30/11"),]

1 Comment

This doesn't seem to work when date is in as.POSIXct class !
4

cool way is to use Negate function to create new one:

`%ni%` <- Negate(`%in%`) 

than you can use it to find not intersected elements

Comments

2

In regards to some of the questions above, here is a tidyverse compliant solution. I used anti_join from dplyr to achieve the same effect:

library(tidyverse)

numbers <- tibble(numbers = c(1:10))
numbers_to_remove <- tibble(number = c(3, 4, 5))

numbers %>%
  anti_join(numbers_to_remove)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.