如何关联data.table并根据条件标记ID对应的高峰时段?
嘿,这个需求在时间序列数据处理里挺常见的!我来帮你用data.table的高效方式搞定这个高峰时段标记的问题~
首先得提醒你一下:别用c当变量名呀,它是R的内置函数,容易引发冲突,我先把你的高峰时段表重命名为rush_hours啦。
核心思路
你的高峰时段有两种情况:
- 常规时段:
start <= end(比如id1的3-9点),直接判断小时是否在[start, end]区间内 - 跨天时段:
start > end(比如id3的9点到次日4点),需要判断小时是否大于等于start或者 小于等于end
实现代码
library(data.table) # 你的原始数据 DT=data.table(id=c(rep(1,24),rep(2,24),rep(3,24)), hour=c(rep(0:23,3)), val=c(rep(c(18,36,27,18,36,39,99,99,72,81,54,72,18,9,36,27,18,90,36,27,18,45,54,63),3))) # 重命名高峰时段表,避免和内置函数c()冲突 rush_hours = data.table(id=c(1,2,3),start=c(3,6,9),end=c(9,12,4)) # 用data.table连接+条件判断添加rush列(结果为TRUE/FALSE) DT[ rush_hours, on = .(id), rush := fifelse( start <= end, hour >= start & hour <= end, hour >= start | hour <= end ) ]
扩展调整(可选)
如果需要把标记改成1/0或者文字描述,可以稍微修改代码:
- 改成1/0标记:
DT[ rush_hours, on = .(id), rush := fifelse( start <= end, as.integer(hour >= start & hour <= end), as.integer(hour >= start | hour <= end) ) ]
- 改成文字描述:
DT[ rush_hours, on = .(id), rush := fifelse( start <= end, ifelse(hour >= start & hour <= end, "高峰", "非高峰"), ifelse(hour >= start | hour <= end, "高峰", "非高峰") ) ]
验证结果
你可以用下面的代码检查id3的跨天高峰时段是否正确标记:
DT[id == 3, .(hour, rush)]
内容的提问来源于stack exchange,提问作者Ricky
相关产品推荐
相关产品推荐

