首页 > 解决方案 > 根据时差删除重复项并在重复项附近折叠

问题描述

我有一个如下所示的数据框

DF = structure(list(Age_visit = c(48, 48, 48, 49, 49, 77), Date_1 = c("8/6/2169 9:40", "8/6/2169 9:40", 
                                                                     "8/6/2169 9:41", "8/6/2169 9:42", "24/7/2169 8:31", "12/9/2169 10:30", 
                                                                     "19/6/2237 12:15"), Date_2 = c("NA-NA-NA NA:NA:NA", "NA-NA-NA NA:NA:NA", "NA-NA-NA NA:NA:NA", 
                                                                                                            "NA-NA-NA NA:NA:NA", "NA-NA-NA NA:NA:NA", "NA-NA-NA NA:NA:NA", 
                                                                                                            "NA-NA-NA NA:NA:NA"), person_id = c("21",
                                                                                                                                                  "21", 
                                                                                                                                                  "21", 
                                                                                                                                                  "21", 
                                                                                                                                                  "21", 
                                                                                                                                                  "21", 
                                                                                                                                                  "31"
                                                                                                            ), enc_id = c("A21BC","A21BC", 
                                                                                                                                       "A22BC", 
                                                                                                                                       "A23BC", 
                                                                                                                                       "A24BC", 
                                                                                                                                       "A25BC", 
                                                                                                                                       "A31BC"
                                                                                                            )), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"
                                                                                                            ))

数据框

  Age_visit Date_1          Date_2            person_id enc_id
      <dbl> <chr>           <chr>             <chr>     <chr> 
1        48 8/6/2169 9:40   NA-NA-NA NA:NA:NA  21        A21BC 
2        48 8/6/2169 9:40   NA-NA-NA NA:NA:NA  21        A21BC 
3        48 8/6/2169 9:41   NA-NA-NA NA:NA:NA  21        A22BC 
4        49 8/6/2169 9:42   NA-NA-NA NA:NA:NA  21        A23BC 
5        49 24/7/2169 8:31  NA-NA-NA NA:NA:NA  21        A24BC 
6        77 12/9/2169 10:30 NA-NA-NA NA:NA:NA  31        A31BC 

我有两个要实施的规则/步骤。

规则 1(步骤 1)

首先,删除基于 3 列的重复项,如Date_1, person_id,enc_id

DF[!duplicated(DF[,c('Date_1','person_id','enc_id')]),]  # this will remove 1st row as it's a plain straight forward duplicate

规则 2(步骤 2)

从步骤 1 的输出中,如果这些记录之间的时间差小于小时,则根据时间将附近重复的记录(注意列中的微小差异)折叠成一条记录DATE_1enc_id

例如,如果您看到person_id = 21,您可以看到在第 1 步之后,他所有的Date_1时间值都在同一天,但差异只有一分钟(9:40 --> 9:41 --> 9:42)。由于不到一个小时(60 分钟),我们将它们全部折叠成一条记录并仅保留第一条记录(即 9:40)。我们对数据框中的每个主题进行此检查

我已经根据几列删除了重复项,如下所示

DF[!duplicated(DF[,c('Date_1','person_id','enc_id')]),]

我希望我的输出如下所示

  Age_visit Date_1          Date_2            person_id enc_id
      <dbl> <chr>           <chr>             <chr>     <chr> 
1        48 8/6/2169 9:40   NA-NA-NA NA:NA:NA  21        A21BC 
4        49 24/7/2169 8:31  NA-NA-NA NA:NA:NA  21        A24BC 
5        77 12/9/2169 10:30 NA-NA-NA NA:NA:NA  31        A31BC 

标签: rdataframedplyrdata.tabletidyr

解决方案


滚动连接选项使用data.table

DT[, c("rn", "hrago") := .(.I, Date_1 - 60 * 60)]
DT[DT[DT, on=.(person_id, Date_1=hrago), roll=-Inf, unique(rn)]]

输出:

   Age_visit              Date_1 person_id enc_id rn               hrago
1:        48 2169-06-08 09:40:00        21  A21BC  1 2169-06-08 08:40:00
2:        49 2169-07-24 08:31:00        21  A24BC  5 2169-07-24 07:31:00
3:        77 2169-09-12 10:30:00        31  A31BC  6 2169-09-12 09:30:00

数据:

library(data.table)
DT <- fread("Age_visit Date_1    person_id enc_id
48 8/6/2169-9:40    21        A21BC 
48 8/6/2169-9:40    21        A21BC 
48 8/6/2169-9:41    21        A22BC 
49 8/6/2169-9:42    21        A23BC 
49 24/7/2169-8:31   21        A24BC 
77 12/9/2169-10:30  31        A31BC") 
DT[, Date_1 := as.POSIXct(Date_1, format="%d/%m/%Y-%H:%M")]

解释:

1)DT[DT, on=.(person_id, Date_1=hrago),person_id从两个表以及Date_1从右表和hrago从左表使用的自连接。

2)roll=-Inf如果未找到与左表中的观察结果相同的匹配项,则将右表中的观察结果向后滚动

3)unique(rn)从右表中获取唯一行,然后为这些行过滤表。


推荐阅读