我有两个数据表如下:
DT1
id start_time end_time
604 2017-08-10 18:44:14 2017-08-11 19:33:17
604 2017-08-10 20:38:20 2017-08-11 20:44:44
604 2017-08-10 20:54:26 2017-08-11 20:58:48
604 2017-08-10 21:35:50 2017-08-11 22:03:14
604 2017-08-10 22:05:42 2017-08-11 22:17:12
.......
DT2
id t1 t2
604 2017-08-10 18:40:14 2017-08-11 18:44:14
604 2017-08-10 18:44:14 2017-08-11 18:47:14
604 2017-08-10 19:44:14 2017-08-11 19:47:14
604 2017-08-10 20:30:14 2017-08-11 20:42:20
604 2017-08-10 21:44:14 2017-08-11 21:49:14
604 2017-08-10 22:44:14 2017-08-11 22:48:14
...
从这两个中我想确定DT2行的累积位于DT的范围之间!例如,第1行从2017-08-10 18:44:14 to 2017-08-11 19:33:17
开始所以我想在那段时间内在DT中积累时间并在DT1中作为eah行的列附加
例如,第一行就像
id start_time end_time durationFromDT2
604 2017-08-10 18:44:14 2017-08-11 19:33:17 420
604 2017-08-10 20:38:20 2017-08-11 20:44:44 240
420是因为(2017-08-11 18:44:14-2017-08-10 18:40:14)+(2017-08-11 18:47:14-2017-08-10 18:44:14)
。如果DT2在这段时间内没有出现,那么我希望它为0.同样明智的我也必须按照许多id分组。
240因为时间是(2017-08-11 20:42:20-2017-08-10 20:38:20)
所以它基本上是DT1在DT1时间段内的覆盖范围 我尝试在行中循环但是没有顺利。相反,我正在寻找任何 dplyr 或数据表解决方案。因为循环不能正常工作
感谢任何帮助。
答案 0 :(得分:2)
假设评论中建议的纠正措施是正确的,请在下面找到dplyr
解决方案:
merge(DT1, DT2, by = "id", all = TRUE) %>%
filter(t2 >= start_time, t1 <= end_time) %>%
mutate(t1_adj = if_else(start_time > t1, start_time, t1),
t2_adj = if_else(end_time < t2, end_time, t2),
difftime = difftime(t2_adj, t1_adj, units = "secs")) %>%
group_by(id, start_time, end_time) %>%
summarize(durationFromDT2 = sum(difftime)) %>%
right_join(DT1) %>%
mutate(durationFromDT2 = coalesce(durationFromDT2, 0))
cross join
每个表之间的所有记录
filter
向下cross join
只包含DT2
次 DT1
区间内的时间点。
mutate
_adj
使用了列来强制t1
和t2
次在DT1
开始和结束时间点之间保持约束,然后计算时间间隔。
group
和summarize
DT1
条记录的持续时间。
要列出最终结果中的所有NULL
条记录,请再次right_join
DT1
表格。
Replace
NA
s为0。
结果如下:
# A tibble: 5 x 4 # Groups: id, start_time [5] id start_time end_time durationFromDT2 <int> <dttm> <dttm> <time> 1 604 2017-08-10 18:44:14 2017-08-10 19:33:17 180 secs 2 604 2017-08-10 20:38:20 2017-08-10 20:44:44 240 secs 3 604 2017-08-10 20:54:26 2017-08-10 20:58:48 0 secs 4 604 2017-08-10 21:35:50 2017-08-10 22:03:14 300 secs 5 604 2017-08-10 22:05:42 2017-08-10 22:17:12 0 secs
来自OP的可重现(整流)样本数据帧如下:
library(lubridate)
DT1 <-
read.table(text = "
id start_date start_time end_date end_time
604 2017-08-10 18:44:14 2017-08-10 19:33:17
604 2017-08-10 20:38:20 2017-08-10 20:44:44
604 2017-08-10 20:54:26 2017-08-10 20:58:48
604 2017-08-10 21:35:50 2017-08-10 22:03:14
604 2017-08-10 22:05:42 2017-08-10 22:17:12
", header = TRUE, stringsAsFactors = FALSE) %>%
mutate(start_time = ymd_hms(paste(start_date, start_time)),
end_time = ymd_hms(paste(end_date, end_time))) %>%
select(-c(start_date, end_date))
DT2 <-
read.table(text = "
id d1 t1 d2 t2
604 2017-08-10 18:40:14 2017-08-10 18:44:14
604 2017-08-10 18:44:14 2017-08-10 18:47:14
604 2017-08-10 19:44:14 2017-08-10 19:47:14
604 2017-08-10 20:30:14 2017-08-10 20:42:20
604 2017-08-10 21:44:14 2017-08-10 21:49:14
604 2017-08-10 22:44:14 2017-08-10 22:48:14
", header = TRUE, stringsAsFactors = FALSE) %>%
mutate(t1 = ymd_hms(paste(d1,t1)),
t2 = ymd_hms(paste(d2,t2)),
) %>%
select(-c(d1, d2))