首页 > 解决方案 > 根据事务是否至少包含 R 中时间范围的一部分来提取数据子集

问题描述

我有一个包含不同事务的数据框df 。每个事务都有一个开始日期和一个结束日期。为此的两个变量是start_timeend_time。它们属于POSIXct类。它们的外观示例如下“2018-05-23 23:40:00”“2018-06-24 00:10:00”。df中大约有 13000 个事务,如果不是全部,我想提取至少包含一点指定时间间隔的所有事务。时间间隔或范围是 20:00:00 - 8:00:00 所以基本上 8 PM =< interval < 8 AM

我正在尝试使用dplyr和函数filter()来执行此操作,但是我的问题是我不确定如何编写布尔表达式。到目前为止,我用代码编写的是这样的:

df %>% filter(hour(start_time) >= 20 | hour(start_time) < 8 |hour(end_time) >= 20 | hour(end_time) < 8 )

我想也许这会得到至少包含该间隔的一部分的所有事务,但后来我想到了可能在该间隔之外开始和结束的事务,但它们的持续时间太长,以至于它包含间隔中的那些小时。我想可能会添加| duration > 12,因为任何持续时间超过 12 小时的开始时间都将包含该时间间隔的一部分。但是,我觉得这段代码太长了,必须有更简单的方法,但我不知道怎么做。

标签: rdataframetimedplyrintervals

解决方案


我将从一个示例数据框开始,因为df问题中没有给出示例:

library(lubridate)
library(dplyr)

set.seed(69)
dates <- as.POSIXct("2020-04-01") + days(sample(30, 10, TRUE))
start_time <- dates + seconds(sample(86400, 10, TRUE))
end_time  <- start_time + seconds(sample(50000, 10, TRUE))
df <- data.frame(Transaction = LETTERS[1:10], start_time, end_time)

df
#>    Transaction          start_time            end_time
#> 1            A 2020-04-18 16:51:03 2020-04-19 00:05:54
#> 2            B 2020-04-28 21:32:10 2020-04-29 06:18:06
#> 3            C 2020-04-03 02:12:52 2020-04-03 06:11:20
#> 4            D 2020-04-17 19:15:43 2020-04-17 21:01:52
#> 5            E 2020-04-09 11:36:19 2020-04-09 19:01:14
#> 6            F 2020-04-14 20:51:25 2020-04-15 06:08:10
#> 7            G 2020-04-08 12:01:55 2020-04-09 01:45:53
#> 8            H 2020-04-16 01:43:38 2020-04-16 04:22:39
#> 9            I 2020-04-08 23:11:51 2020-04-09 09:04:26
#> 10           J 2020-04-07 12:28:08 2020-04-07 12:55:42

我们可以列举匹配的可能性如下:

  1. 08:00 之前或 20:00 之后的任何开始时间
  2. 08:00 之前或 20:00 之后的任何停止时间
  3. 停止时间和开始时间在不同的日期。

使用一点模块化数学,我们可以这样写:

df %>% filter((hour(start_time) + 12) %% 20 > 11 | 
              (hour(end_time) + 12) %% 20 > 11 | 
              date(start_time) != date(end_time))
#>   Transaction          start_time            end_time
#> 1           A 2020-04-18 16:51:03 2020-04-19 00:05:54
#> 2           B 2020-04-28 21:32:10 2020-04-29 06:18:06
#> 3           C 2020-04-03 02:12:52 2020-04-03 06:11:20
#> 4           D 2020-04-17 19:15:43 2020-04-17 21:01:52
#> 5           F 2020-04-14 20:51:25 2020-04-15 06:08:10
#> 6           G 2020-04-08 12:01:55 2020-04-09 01:45:53
#> 7           H 2020-04-16 01:43:38 2020-04-16 04:22:39
#> 8           I 2020-04-08 23:11:51 2020-04-09 09:04:26

您可以检查所有时间是否至少部分在给定范围内,并且两个删除的行不在。


推荐阅读