删除 R 数据框中重复的行,组中第一个,与组中第一个共享 ID 或以上所有

Remove rows in R dataframe that are duplicates, first in group, share ID with first in group or all of the above

我有一个包含日期和标识符的数据框。我想过滤此数据框以结束具有 1) 原始数据框中其他人的连续日期的行,2) 不是一组连续日期中的第一个,3) 与行的 ID 不同在第一个日期之后的一组连续日期中的第一个,4) 基于 ID 进行重复数据删除。例如

Date <-  as.Date('2019.01.01', '2019.01.02', '2019.01.03', '2019.01.04', '2019.01.10',  '2019.01.11', '2019.01.12', '2019.01.13', '2019.01.18', '2019.01.22', '2019.01.27', ' 2019.01.28', '2019.01.30')
ID <- c('A', 'A', 'C', 'C', 'D', 'E', 'A', 'F', 'D', 'F', 'F', 'C', 'G')
df <- data.frame(Date, ID)

 Date        ID
 2019.01.01  A
 2019.01.02  A
 2019.01.03  C
 2019.01.04  C
 2019.01.10  D
 2019.01.11  E
 2019.01.12  A
 2019.01.13  F
 2019.01.18  D
 2019.01.22  F
 2019.01.27  F
 2019.01.28  C
 2019.01.30  G

结束
     Date        ID
     2019.01.03  C
     2019.01.11  E
     2019.01.13  F

不胜感激!

首先我们定义元素,它们是“组中的第一个”:

library(dplyr)
library(lubridate)

first_of_groups <- df %>% 
  mutate(Date = as_date(Date)) %>% 
  group_by(grp_cond_3 = cumsum((Date - lag(Date, default = first(Date))) != 1)) %>% 
  filter(n() > 1) %>% 
  slice_min(Date)

我们需要这个 data.frame 来删除这个元素。接下来我们构建 data.frame:

df %>% 
  mutate(Date = as_date(Date),
         condition_1 = Date == lag(Date) + 1,
         condition_2 = replace_na(condition_1, FALSE)) %>% 
  left_join(first_of_groups, by = "ID", suffix = c("", ".y")) %>% 
  mutate(condition_3 = is.na(Date.y) | Date < Date.y) %>% 
  ungroup() %>% 
  filter(condition_1, condition_2, condition_3) %>% 
  group_by(ID) %>% 
  slice(1) %>% 
  select(Date, ID) %>%
  ungroup()

这个returns

# A tibble: 3 x 2
  Date       ID   
  <date>     <chr>
1 2019-01-03 C    
2 2019-01-11 E    
3 2019-01-13 F  

基本上condition_1condition_2是一样的。我们取日期并计算与前一个日期的差异。如果差异等于 1,我们知道两件事:

  • 它不是一组连续天数的第一个元素
  • 连续几天

对于“first of groups”条件,我们在您的数据集中搜索与前一行的差异不为 1 的行。假设没有具有相同日期的行,我们可以构建使用此信息中的 cumsum 建立一个分组号码。

接下来我们过滤“真实”组,即具有多个元素的组。然后我们取这些组的第一个元素。

使用这个 first_of_groups data.frame 我们可以通过左连接 first_of_groups 和我们的原始数据框来构建 condition_3。满足 condition_3 first_of_groups data.frame (is.na(Date.y)) 中的 ID 不匹配或日期为 lesser/smaller(位于) ID 成为“小组第一”的日期。

最后的 condition_4 是通过在剩余的 data.frame 中取每个 ID 的第一个元素创建的。