我有一个如下所示的数据框
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)
首先,根据 Date_1
、person_id
、enc_id
等 3 列去除重复项
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),
是使用来自两个表和 Date_1< 的
来自右表,person_id
的自连接hrago
来自左表。
2) roll=-Inf
如果没有找到与左表中的观察值相同的匹配项,则向后滚动右表中的观察值
3) unique(rn)
从右表中获取唯一行,然后为这些行过滤表。
关于根据时差删除重复项并折叠附近的重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61269745/