如何用dplyr筛选包含20:00-次日8:00时段的POSIXct交易数据?
解决交易时段筛选问题:包含晚8点至次日早8点的交易
你的问题很典型——只检查起止时间的小时会漏掉那些跨天、全程覆盖目标时段的交易。我们可以换个思路,排除那些完全处于早8点到晚8点之间的交易,剩下的就是符合要求的(即至少部分时段落在晚8到早8的交易)。
问题根源
你原来的代码:
df %>% filter(hour(start_time) >=20 | hour(start_time) <8 | hour(end_time)>=20 | hour(end_time)<8)
只判断了起止时间的小时是否在目标区间,但比如start_time=9:00、end_time=次日9:00的交易,虽然起止都不在目标时段,但全程包含了晚8到早8,这类交易就会被漏掉。
改进后的代码
我们用取反逻辑来实现,只排除完全落在当日8:00-20:00的交易:
library(dplyr) library(lubridate) # 用来处理时间,若未加载请先运行 df_filtered <- df %>% filter( !( as.Date(start_time) == as.Date(end_time) & # 交易在同一天内 hour(start_time) >= 8 & hour(start_time) < 20 & # 开始时间在8-20区间 hour(end_time) >= 8 & hour(end_time) < 20 # 结束时间也在8-20区间 ) )
逻辑解释
这个条件会保留以下所有符合要求的交易:
- 开始时间或结束时间本身就在晚8到早8之间(比如
23:40开始、00:10结束的交易) - 跨天的交易(只要交易跨天,必然会包含晚8到早8的时段,比如9点到次日9点的交易)
- 部分时段覆盖目标区间的交易(比如7点到9点的交易,包含早7点的目标时段)
只有完全在当日8:00-20:00之间的交易会被排除,这正是我们不需要的。
验证案例
我们用几个测试案例验证逻辑:
- ✅ 交易:
start=2018-05-23 23:40:00,end=2018-05-24 00:10:00→ 符合要求,被保留 - ✅ 交易:
start=2018-05-24 09:00:00,end=2018-05-25 09:00:00→ 跨天包含目标时段,被保留 - ❌ 交易:
start=2018-05-24 10:00:00,end=2018-05-24 18:00:00→ 完全在8-20之间,被排除 - ✅ 交易:
start=2018-05-24 07:00:00,end=2018-05-24 09:00:00→ 包含早7点的目标时段,被保留
这样的写法既简洁又覆盖了所有场景,不需要额外判断时长,避免了冗余。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

