I 有序记录集,return 子组中第一个满足条件的值,或 return 未满足条件的最早记录

I an ordered record set, return the first value meeting a criterion in a sub-group, or return the earliest record where the criterion is unmet

我有一个有序记录集的数据框,该数据框与具有唯一 ID (grpid) 的组相关,其中记录是事件(事件),一个组 ID 可能与一个或多个事件相关,但所有事件都有排名顺序变量(ordid)。 我要完成的任务是 return 每个组中符合一组条件的事件顺序中最早的事件。如果没有记录符合条件,只需 return 最早。我需要它们 return 进入一个新的数据集。 因此,在 data.frame 'd' 中的最小可重现示例中,我的标准是 return 每个组中第一个不是以 'x' 或 'y' 开头的事件,但如果所有事件都开始使用 x 或 y 然后接受第一个出现的记录,即使它是 x/y 一个。所以在“a”组的第一个事件中,d21 符合我的标准,所以我的新集合将包括“a”和“d21”。在第二组中有四个记录。前两个被拒绝,但选择了'b''j10',因为它是不以 'x' 或 'y' 开头的最低排名记录。在最后一种情况下,所有记录都以“x”或“y”开头,所以我只想要排名最低的一个,即“x10” 真实的数据集大约有数亿,所以效率是一个考虑因素。下面提供了 MRE 的代码。

#make data.frame of sample data
grpid<-c('a','a','a','b','b','b','b','c','c')
ordid<-c(1,2,3,1,2,3,4,1,2)
event<-c('d21','e30','a10','x89','y77','j10','d17','x10','x22')
d<-data.frame(grpid,ordid,event)
d
#make data.frame of desired output
grpid1<-c('a','b','c')
event1<-c('d21','j10','x10')
out<-data.frame(grpid1,event1)
out

按'grpid'分组,创建索引,其中'event'的第一个字符不是'x'或'y',然后slice第一个元素基于在索引和 if all 上,值是 'x' 或 'y',然后 return 第一个观察值

library(dplyr)
d %>%
    group_by(grpid) %>% 
    mutate(ind = event == event[!substr(event, 1, 1) %in% c('x', 'y')][1]) %>%
    slice(if(all(is.na(ind))) 1 else which(ind)[1]) %>%
    ungroup %>% 
    select(-ordid, -ind)

-输出

# A tibble: 3 × 2
  grpid event
  <chr> <chr>
1 a     d21  
2 b     j10  
3 c     x10  

或使用 summarisecoalesce

d %>% 
   group_by(grpid) %>%
   summarise(event = coalesce(event[!substr(event, 1, 1) %in% 
        c('x', 'y')][1], first(event)))
# A tibble: 3 × 2
  grpid event
  <chr> <chr>
1 a     d21  
2 b     j10  
3 c     x10