使用dplyr在ID级别基于两个条件过滤行

时间:2019-11-12 19:13:44

标签: r dplyr

我有很长的数据,其中给定的对象有4个观察值。我只想包含一个满足以下条件的给定ID:

1)至少有3个

AND

2)至少具有1,2 OR NA之一

我的数据结构:

df <- data.frame(id=c(1,1,1,1,2,2,2,2,3,3,3,3), a=c(NA,1,2,3, NA,3,2,0, NA,NA,1,1))

我失败的尝试(我得到一个空的数据框):

df %>% dplyr::group_by(id) %>% filter(a==3 & a %in% c(1,2,NA)) 

谢谢!

3 个答案:

答案 0 :(得分:3)

一个选项是按“ id”分组,创建逻辑以返回单个TRUE / FALSE作为输出。根据OP的帖子,我们需要在“ a”列中同时使用值“ 3”和值1、2,NA之一。因此,3 %in% a返回长度为1的逻辑向量,然后将any包装在第二个集合上,在该集合中我们对多个值进行比较或检查NA元素(is.na),将两个逻辑合并使用&

输出
library(dplyr)
df %>% 
  group_by(id) %>%
  filter((3 %in% a) & any(c(1, 2) %in% a|is.na(a)) )
# A tibble: 8 x 2
# Groups:   id [2]
#     id     a
#  <dbl> <dbl>
#1     1    NA
#2     1     1
#3     1     2
#4     1     3
#5     2    NA
#6     2     3
#7     2     2
#8     2     0

答案 1 :(得分:3)

我已经做了很长的路要走,以展示一个想法如何运作。您可以对此进行合并。

df %>%
  group_by(id) %>%
  mutate(has_3 = sum(a == 3, na.rm = T) > 0,
         keep_me = has_3 & (sum(is.na(a)) > 0 | sum(a %in% c(1, 2)) > 0)) %>%
  filter(keep_me == TRUE) %>%
  select(id, a)

     id     a
  <dbl> <dbl>
1     1    NA
2     1     1
3     1     2
4     1     3
5     2    NA
6     2     3
7     2     2
8     2     0

答案 2 :(得分:1)

在我阅读时,过滤器应保留ID 1和2。因此,我将使用all / any的组合:

    df  %>% 
      group_by(id) %>% 
      filter(all(3 %in% a) & any(c(1,2,NA) %in% a))