dplyr如何按组分组,然后根据每个组的第一行条件过滤行?

4

我有一个简单的数据框,例如

df <- data.frame(x=c(1,1,1,1,2,2,2,3,3,3),
                 y=c('a','b','a','c','e','d','e','a','f','c'))

enter image description here

我希望按x分组,然后如果每个x组的第一行y == 'a',则只获取y == 'a' | y == 'c'的行。
因此,我期望结果将具有第1、3、4、8、10行。
非常感谢。
2个回答

3

按 'x' 进行分组后,创建一个 & 条件 - 1) 检查 'y' 的 first 值是否为 'a',2) 检查列中的值是否为 'a'、'c'。

library(dplyr)
df %>%
   group_by(x) %>%
   filter('a' == first(y), y %in% c('a', 'c')) %>%
   ungroup

-输出

# A tibble: 5 × 2
      x y    
  <dbl> <chr>
1     1 a    
2     1 a    
3     1 c    
4     3 a    
5     3 c 

如果我们有额外的规则,创建一个名为list的列表,在这个列表中,名称将是'y'的第一个值,需要过滤的值的向量,然后根据'y'的第一个值提取list元素,并在逻辑表达式中使用该向量和%in%操作符。

df %>%
    group_by(x) %>%
    filter(y %in% list(a = c('a', 'c'), e = 'e')[[first(y)]]) %>%
    ungroup

-输出

# A tibble: 7 × 2
      x y    
  <dbl> <chr>
1     1 a    
2     1 a    
3     1 c    
4     2 e    
5     2 e    
6     3 a    
7     3 c   

谢谢,它有效。但是如果我想在添加“if”条件时使其更复杂,例如如果每个组的第一行具有y == a,则获取具有y == a或y == c的行,但如果每个组的第一行具有y == e,则获取具有y == e的行?因此,现在我期望结果中添加2行(第5行和第7行)。 - game_of_lies
@game_of_lies 试试更新。 - akrun
1
@game_of_lies 你也可以使用 if/else,但是这种方式更容易通过超过2个条件。 - akrun
1
你的逻辑在我的真实数据上运行良好,非常感谢 Akrun。 - game_of_lies

0

这里有另一种 dplyr 的选项

> df %>%
+   filter(y %in% c("a", "c") & ave(y == "a", x, FUN = first))
  x y
1 1 a
2 1 a
3 1 c
4 3 a
5 3 c

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