按组保留列中第一次出现某个值之前的所有行。允许没有该值的组。

11

我有一个像这样的数据框:

> df
  id type
1  1    a
2  1    a
3  1    b
4  1    a
5  1    b
6  2    a
7  2    a
8  2    b
9  3    a
10 3    a

我想要保留每个组(id)中 type 列的第一个出现值为 'b' 之前的所有行。对于没有 type 为 'b' 的组,我想要保留它们所有的行。
生成的数据框应该长这样:
> dfnew
  id type
1  1    a
2  1    a
3  1    b
4  2    a
5  2    a
6  2    b
7  3    a
8  3    a

我尝试了以下代码,但它保留了额外的行,这些行在第一个出现'b'之后仍具有值'a',并且仅排除了额外的'b'出现,这不是我想要的。请看下面的第4行。我想要摆脱它。
> df %>% group_by(id) %>% filter(cumsum(type == 'b') <= 1)
Source: local data frame [7 x 2]
Groups: id

  id type
1  1    a
2  1    a
3  1    b
4  1    a
5  2    a
6  2    a
7  2    b
8  3    a
9  3    a
1个回答

20

你可以将 match 或者 whichslice 结合使用,或者(如@Richard所提到的)使用which.max


library(dplyr)
df %>% 
  group_by(id) %>% 
  slice(if(any(type == "b")) 1:which.max(type == "b") else row_number())    
# Source: local data table [8 x 2]
# Groups: id
# 
#   id type
# 1  1    a
# 2  1    a
# 3  1    b
# 4  2    a
# 5  2    a
# 6  2    b
# 7  3    a
# 8  3    a

或者你可以尝试使用data.table

library(data.table)
setDT(df)[, if(any(type == "b")) .SD[1:which.max(type == "b")] else .SD, by = id]
#    id type
# 1:  1    a
# 2:  1    a
# 3:  1    b
# 4:  2    a
# 5:  2    a
# 6:  2    b
# 7:  3    a
# 8:  3    a

或者只需使用 which.max() - Rich Scriven
我在我的数据框中遇到了这个错误:错误:NA/NaN参数。我认为原因是并非所有的“groups”类型都等于“b”。 - Gopala
使用 slice(1:which.max(type == "b")) 就不会出现那个错误了,但在这种情况下,您的期望输出是什么? - David Arenburg
我根据这个用例和期望的输出修改了我的问题。我使用的命令处理了这种情况,但没有排除在遇到类型“b”之后发生的行。我将尝试which.max()。 - Gopala
好的,看看我的编辑和另一个使用 data.table 的解决方案。 - David Arenburg

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