基于向量的值过滤数据框行

18
什么是从数据帧中过滤行的最佳方法,当要删除的值存储在向量中时? 在我的情况下,我有一个带日期的列,并想要删除几个日期。 我知道如何使用“!=”删除对应于一天的行,例如:
m[m$date != "01/31/11", ]

为了删除一个向量中指定的多个日期,我尝试了以下方法:

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

然而,这会导致一个警告信息:

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

如何基于多个值应用过滤器的正确方法?

4个回答

40

nzcoops的建议是完全正确的。我一段时间前在R Chat中提出了这个问题,Paul Teetor建议定义一个新函数:

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

然后可以按照以下方式使用:

foo <- letters[1:6]

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

不用说,这个小工具现在已经在我的R配置文件中了,而且经常被使用。


不错。每当我需要输入像!(x %in% y)这样的内容时,总会分散我的注意力...非常好的提示。 - Peter M
2
我认为 dplyr 无法处理这个问题,例如:filter(df, foo %notin% c("a", "c", "e")) - tumultous_rooster
1
这只是一条注释!我试图在一个filter调用中使用%noin%,但不出所料它没有起作用。 - tumultous_rooster
@MattO'Brien,我在下面使用anti_join发布了一个等效的内容。. . - Ben G

14

我认为你想要的是:

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

当日期是 as.POSIXct 类型时,似乎无法正常工作! - vagabond

4
使用Negate函数来创建一个新的函数是一种很酷的方法:
`%ni%` <- Negate(`%in%`) 

您可以使用它来查找未相交的元素。


2

关于上述问题,这里提供一种符合tidyverse标准的解决方案。我使用了dplyr中的anti_join来获得相同的效果:

library(tidyverse)

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

numbers %>%
  anti_join(numbers_to_remove)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接