如何在R中使用dplyr统计时间序列数据穿过指定阈值的次数
实现逻辑
判断时间序列穿越阈值的核心规则是:相邻两个时间点的深度值分别位于阈值两侧,即一侧大于50、另一侧小于50,每出现一次该情况即计为1次穿越。
依赖包加载
library(dplyr)
完整实现代码
# 导入示例数据,你可以替换为自己的数据集 df <- structure(list(Date.time = structure(c(1458626300, 1458626310, 1458626320, 1458626330, 1458626340, 1458626350, 1458626360, 1458626370, 1458626380, 1458626390, 1458626400, 1458626410, 1458626420, 1458626430, 1458626440, 1458626450, 1458626460, 1458626470, 1458626480, 1458626490, 1458626500, 1458626510, 1458626520, 1458626530, 1458626540, 1458627840, 1458627850, 1458627860, 1458627870, 1458627880, 1458627890, 1458627900, 1458627910, 1458627920, 1458627930, 1458627940, 1458627950, 1458627960, 1458627970, 1458627980, 1458627990, 1458628000, 1458628010, 1458628020, 1458628030, 1458628040, 1458628050, 1458628060, 1458628070, 1458628080, 1458628090, 1458628100, 1458628110, 1458628120, 1458628130, 1458628140, 1458628150, 1458628160, 1458630830, 1458630840, 1458630850, 1458630860, 1458630870, 1458630880, 1458630890, 1458630900, 1458630910, 1458630920, 1458630930, 1458630940), tzone = "UTC", class = c("POSIXct", "POSIXt")), Depth = c(67.5, 66, 63.5, 62, 59.5, 57.5, 56, 54.5, 53.5, 52.5, 51, 49.5, 48, 46.5, 45, 44, 42, 40.5, 37.5, 35, 33, 33, 32.5, 30, 27, 26.5, 28, 29, 31.5, 33, 32.5, 32.5, 32.5, 32, 32, 32.5, 33, 34.5, 36.5, 38.5, 40.5, 41.5, 43, 44.5, 46.5, 49.5, 51.5, 53, 54.5, 56, 58, 59, 60.5, 62, 64.5, 66, 67, 69, 69.5, 67, 64, 62.5, 60, 57, 55.5, 51.5, 48.5, 46, 43, 40.5)), row.names = c(NA, -70L), class = c("data.table", "data.frame") # 设置阈值 threshold <- 50 # 统计穿越次数 cross_count <- df %>% # 按时间排序,避免原始数据顺序错乱导致统计错误,已确认顺序可省略该行提升效率 arrange(Date.time) %>% # 提取上一行的深度值 mutate(prev_depth = lag(Depth)) %>% # 过滤无前置值的首行,判断是否满足穿越条件 filter(!is.na(prev_depth), (prev_depth > threshold & Depth < threshold) | (prev_depth < threshold & Depth > threshold)) %>% # 统计符合条件的行数即为穿越总次数 nrow()
运行结果
针对示例数据运行代码得到cross_count = 3,和示例场景的预期结果一致。
注意事项
- 若业务规则中深度刚好等于50的情况需要计入穿越,可自行调整判断条件中的
</>为<=/>= - 该方案为向量化运算,百万级数据量运行无压力,耗时仅需毫秒级
内容的提问来源于stack exchange,提问作者Meg.abytes
相关产品推荐
相关产品推荐

