r - 根据时差删除重复项并在重复项附近折叠
问题描述
我有一个如下所示的数据框
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_1
。enc_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
解决方案
滚动连接选项使用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)
从右表中获取唯一行,然后为这些行过滤表。
推荐阅读
- azure-devops - 部署的 DevOps 阶段
- sql - 除 NULL 记录外按 ID 分组
- javascript - 使用 jquery 的 Boggle 类型单词检查器
- solr - 如何索引具有 geojson 作为 Solr 中的字段的文档?
- java - 尝试将 XML 值转换为地图
- php - “可能重定向随机 URL”
- sql - 为什么使用 SQL 数据透视表会出现语法错误?
- maven - 使用fabric8 docker-maven-plugin 在远程docker daemon 上构建镜像
- php - 在 PHP 中从 2 个不同的数组填充 HTML 表
- graphql - 带有官方 Graphql 教程的“无法在 CreateUser 类型上查询字段 'id'”