R 删除重复项并基于时差在重复项附近折叠
我有一个如下所示的数据框R 删除重复项并基于时差在重复项附近折叠,r,dataframe,dplyr,data.table,tidyr,R,Dataframe,Dplyr,Data.table,Tidyr,我有一个如下所示的数据框 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
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"
))
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
数据帧
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
规则2(步骤2)
从步骤1的输出中,如果重复记录之间的时差小于小时,则根据时间将重复记录(注意DATE_1
和enc_id
列中的微小差异)折叠到单个记录中
例如,如果您看到person\u id=21
,您可以看到在步骤1之后,他的所有Date\u 1
时间值都在同一天,但差值只有一分钟(9:40-->9:41-->9:42)。因为不到一个小时(60分钟),我们将所有记录折叠成一个记录,只保留第一个记录(9:40)我们对数据框中的每个主题进行此检查
我已经根据如下所示的几个列删除了重复项
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"
))
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
我希望我的输出如下所示
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"
))
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
年龄\u就诊日期\u 1日期\u 2人员\u id enc\u id
1488/6/2169:40 NA-NA-NA:NA:NA 21 A21BC
4 49 24/7/2169 8:31 NA-NA-NA:NA:NA 21 A24BC
57712/9/2169 10:30 NA-NA-NA:NA:NA 31 A31BC
通过检查连续时差,您可以在同一步骤中同时执行这两项操作。重复项的时差为0:
library(dplyr)
library(lubridate)
DF %>%
group_by(person_id)%>%
mutate(Date_1 = dmy_hm(Date_1)) %>%
arrange((Date_1)) %>%
filter(c(5000,diff(Date_1))>3600)
Age_visit Date_1 Date_2 person_id enc_id
<dbl> <dttm> <chr> <chr> <chr>
1 48 2169-06-08 09:40:00 NA-NA-NA NA:NA:NA 21 A21BC
2 49 2169-07-24 08:31:00 NA-NA-NA NA:NA:NA 21 A24BC
3 77 2169-09-12 10:30:00 NA-NA-NA NA:NA:NA 31 A25BC
您的问题可以使用dplyr管道解决
- 第一步使用
解决重复问题distinct()
- 秒步骤将Date_1列更改为Datetime类型(计算时差所必需)
- 第三步使用
添加带有上一个时间戳的列。该列必须位于person\u id上的lag()
中,以确保时间戳不会转移到其他人。此外,确保日期排列正确(使用group\u by()
)也很重要arrange()
- 第四步计算与前一个时间戳的时间差(以秒为单位)。这将给出第一行人员的NA
- 第五步删除时差小于一小时的所有记录
- 最后一步将删除管道中创建的所有其他列
使用
数据的滚动联接选项。表
:
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
数据:
库(data.table)
DT感谢您的回复。我将尝试您的答案,并在需要时更新答案。嗨,很抱歉,R是新手。我的输入数据是数据帧格式。因此,我必须将数据帧转换为数据表才能使用此解决方案?谢谢。我正在重述数据表和滚动联接,但您能帮助我了解这行代码的作用吗DT[DT[DT,on=(person\u id,Date\u 1=hrago),roll=-Inf,unique(rn)]
我知道它正在向后滚动,并基于person\u id和hrago这两个键进行连接。将DT数据表连接到自身???@很好,我在postYes中添加了一些解释,这一点很好。滚动连接选项更好、更干净。谢谢!