R dplyr将行保留到列中第一次出现的值

Gop*_*ala 7 r dplyr

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

> 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
Run Code Online (Sandbox Code Playgroud)

我希望将每个组(id)的所有行保留到类型列中第一次出现的值"b".对于没有类型'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
Run Code Online (Sandbox Code Playgroud)

我尝试了下面的代码,但它保留了超出第一次出现'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
Run Code Online (Sandbox Code Playgroud)

Dav*_*urg 12

你可以组合matchwhichslice或(如@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
Run Code Online (Sandbox Code Playgroud)

或者你可以尝试一下 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
Run Code Online (Sandbox Code Playgroud)