如何移除R语言data.table中含连续三个零的时间序列行?
解决data.table中移除含连续三个零的时间序列分组问题
首先还原你的示例数据:
library(data.table) dt <- data.table( Species = c(rep("A", 6), rep("B", 6), rep("C", 6)), Location = c("X", "X", "X", "X", "Y", "Y", "X", "X", "X", "X", "X", "X", "Y", "Y", "Y", "Y", "Y", "Y"), Year = c(2010, 2011, 2012, 2013, 2010, 2011, 2010, 2011, 2012, 2013, 2014, 2015, 2010, 2011, 2012, 2013, 2014, 2015), Count = c(3, 4, 10, 1, 5, 0, 3, 0, 0, 0, 2, 1, 0, 10, 11, 14, 12, 9) )
简洁实现方案
利用data.table的分组特性和滚动窗口函数,一行代码完成需求:
dt_filtered <- dt[, if (!any(frollsum(Count == 0, n = 3, align = "left") == 3)) .SD, by = .(Species, Location)]
代码逻辑解释
- 分组定位独立时间序列:
by = .(Species, Location)确保我们以「物种+地点」为单位,每个组合对应一条独立的时间序列。 - 滚动窗口检测连续零:
Count == 0将计数转换为布尔值(0对应TRUE,非0对应FALSE)frollsum(..., n = 3, align = "left")对布尔序列做窗口大小为3的滚动求和,align = "left"表示窗口从当前行开始向后覆盖3行- 当滚动求和结果等于3时,说明存在连续三个0的情况
- 过滤目标分组:
if (!any(...)) .SD仅保留未出现连续三个0的分组,.SD代表当前分组的全部数据。
原代码的问题说明
你的自定义函数存在几个核心问题:
- 未按
Species和Location分组,会把整个数据表当成单一序列处理,无法区分不同的时间序列 - 循环索引错误:
1:nrow(dt)-2实际运算为(1:nrow(dt)) - 2,正确写法应为1:(nrow(dt)-2)才能生成有效索引 - 仅标记了部分行,没有将存在连续零的整个分组全部移除,不符合需求
验证结果
运行上述代码后,dt_filtered会移除Species = B且Location = X的所有行,其余数据完整保留,与预期结果一致。
内容的提问来源于stack exchange,提问作者TEcology
相关产品推荐
相关产品推荐

