按小时查找持续时间

Find duration by hour

我有以下数据帧(长度以秒为单位):

dates<-data.frame(start=as.POSIXct(c("2010-04-03 03:02:38 UTC","2010-04-03 06:03:14 UTC","2010-04-20 03:05:52 UTC","2010-04-20 03:17:42 UTC","2010-04-21 03:09:38 UTC","2010-04-21 07:10:14 UTC","2010-04-21 08:12:52 UTC","2010-04-23 03:13:42 UTC","2010-04-23 03:25:42 UTC","2010-04-23 03:36:38 UTC","2010-04-23 08:58:14 UTC","2010-04-24 03:21:52 UTC","2010-04-24 03:22:42 UTC","2010-04-24 07:24:19 UTC","2010-04-24 07:55:19 UTC")),length=c(3600,300,900,3600,300,900,3600,300,900,3600,300,900,3600,300,3600))

> dates
                 start length
1  2010-04-03 03:02:38   3600
2  2010-04-03 06:03:14    300
3  2010-04-20 03:05:52    900
4  2010-04-20 03:17:42   3600
5  2010-04-21 03:09:38    300
6  2010-04-21 07:10:14    900
7  2010-04-21 08:12:52   3600
8  2010-04-23 03:13:42    300
9  2010-04-23 03:25:42    900
10 2010-04-23 03:36:38   3600
11 2010-04-23 08:58:14    300
12 2010-04-24 03:21:52    900
13 2010-04-24 03:22:42   3600
14 2010-04-24 07:24:19    300
15 2010-04-24 07:55:19   3600

我想按小时计算总时长,例如从 00:00:00 到 01:00:00,从 01:00:00 到 02:00:00 等等。但有时开始于 07:55:19,持续时间为 3600(如最后一行),我需要将其分成 2 并计算 07:00:00 至 08:00:00 期间的 281 秒,并且08:00:00 到 09:00:00 期间 3319 秒。

我会找到 03:00:00-04:00:00 期间的总持续时间,例如:

library(lubridate)

dates$endTime<-dates$start+dates$length
dates$newTime<-format(dates$start, format="%H:%M:%S")
dates$endTime<-format(dates$endTime, format="%H:%M:%S")
dates$dur3<-ifelse(hms(dates$endTime)<hms("04:00:00"), seconds(hms(dates$endTime)-hms(dates$newTime)), seconds(hms("04:00:00")-hms(dates$newTime)))

sum(dates[dates$dur3>0,"dur3"])
12920

我想只计算每行 24 个周期中每个周期的持续时间,然后将它们相加,但是这样做更有效的方法是什么?

这是我对这个问题的看法,尽管我并不完全确定这个任务:首先,我计算接下来几个小时的重叠

dates$rest <- 3600 - as.numeric(format(dates$start, "%M"))*60 - as.numeric(format(dates$start, "%S"))
dates$excess <- dates$length - dates$rest

接下来,我们遍历延伸到下一个小时的那些长度,请记住,这仅在长度限制为 3600 时有效。如示例所示。如果不是,循环需要延长一点。

for(row in which(dates$excess > 0)){
  row_to_copy <- dates[row, ]
  dates[row, "length"] <- dates[row, "length"] - row_to_copy$excess
  row_to_copy$start <- row_to_copy$start + 3600
  row_to_copy$length <- row_to_copy$excess
  dates <-rbind(dates, row_to_copy)
}

有了完成的数据集,我们现在定义了对小时数进行分组的列。请注意,如果我们愿意,我们也可以按 "Date - Hour" 分组。

dates$hours <- format(dates$start, "%H")
res_df <-
  dates %>% 
  group_by(hours) %>%
  summarize(length_total = sum(length))

有了结果

> res_df
# A tibble: 6 x 2
  hours length_total
  <chr>        <dbl>
1 03           13240
2 04            4460
3 06             300
4 07            1519
5 08            6347
6 09             834
> a=dates$start
> b=difftime(a+hours(1)-second(a)-minutes(minute(a)),a,units="secs")
> d=c(pmin(b,dates$length),replace(e<-dates$length-b,e<0,0))
> tapply(d,c(hour(a),hour(a)+1),sum)
    3     4     6     7     8     9 
12920  4780   300  1481  6253   966