R 如何找到两个时间间隔的累计时间
我有两个数据表,如下所示: DT1 DT2 从这两行中,我想确定位于DT!范围之间的DT2行的累积!。例如,第1行从2017-08-10 18:44:14开始到2017-08-11 19:33:17,所以我想取这段时间之间DT中的时间累积,并作为DT1中各行的列附加 例如,第一行是R 如何找到两个时间间隔的累计时间,r,dplyr,data.table,R,Dplyr,Data.table,我有两个数据表,如下所示: DT1 DT2 从这两行中,我想确定位于DT!范围之间的DT2行的累积!。例如,第1行从2017-08-10 18:44:14开始到2017-08-11 19:33:17,所以我想取这段时间之间DT中的时间累积,并作为DT1中各行的列附加 例如,第一行是 id start_time end_time durationFromDT2 604 2017-08-10 18:44:
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)
所以基本上是DT2对DT1时间段的覆盖
我尝试在行中循环,但没有成功。相反,我正在寻找任何dplyr或数据表解决方案。因为循环不起作用
感谢您的帮助。假设评论中建议的纠正措施是正确的,请在下面找到
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))
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))
库(lubridate)
DT1%
变异(开始时间=ymd\U hms(粘贴(开始日期,开始时间)),
结束时间=ymd\U hms(粘贴(结束日期,结束时间))%>%
选择(-c(开始日期、结束日期))
DT2%
突变(t1=ymd_hms(粘贴(d1,t1)),
t2=ymd_hms(粘贴(d2,t2)),
) %>%
选择(-c(d1,d2))
我想你要找的是grep和gsub函数族。如果我没有错的话,我不认为grep用于匹配模式是正确的。但是这里我必须迭代DT2,然后与DT1关联。当结束时间
位于同一行的t1
和t2
之间时,你如何处理这些情况?1)是截止日期都是2017-08-10(而不是2017-08-11)?将DT2的持续时间的单位设置为秒?2) 回复: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)
-您包括的时间不在DT1的开始和结束时间之间。如果条件是时间必须介于DT1次之间,那么第一行加起来不是等于180秒吗?(由于DT1限制范围内的唯一DT2记录是18:44至18:47记录?)1秒@Jenslerssen两个表中的日期显然应该是同一天,以便彼此之间的距离如此之小。对于DT1
中的第一行,只有DT2
中的第二行在其间隔内,而DT2
中的任何行都不在DT1
中第二行的间隔内。简而言之,你真的需要修正你的例子。除此之外,假设所有日期列的格式正确,data.table解决方案将位于这些行中DT2[DT1,sum(difftime(t2,start_time,units=“secs”),na.rm=TRUE),on=。(id,t1>=开始时间,t2抱歉迟到了。结束日期可能会落在不同的日期。当我在我的整个数据中运行它时,这有一些问题。DT2中一天的唯一一行类似于3 2017-09-11 07:43:54 2017-09-11 07:47:26
然后在我的DT1中记录类似于3 2017-09-11 18:44:14 2017-09-11 19:33:17
mDT2=1458是结束时间和开始时间的两倍。在这两者之间我没有延伸。你能提供建议吗?这是因为我在不同的日期有记录。这个解决方案在不同的日期应该可以正常工作。我只能猜测,你可能需要确保你只过滤重叠部分。只需先运行这一行,然后再运行两次检查您是否正在筛选所有不重叠的时段:merge(DT1,DT2,by=“id”,all=TRUE)%%>%filter(t2>=start\u time,t1非常抱歉,这是我的DT2中的错误。非常感谢您了解dplyry,我很高兴能为您提供帮助
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))
# 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
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))