犬只绝育数据集校验逻辑及噪声行去除方法咨询
问题1:统计存在状态反转的犬只数量逻辑
绝育状态不可逆,判定逻辑非常明确:对每只犬的所有记录按事件日期升序排序后,只要存在任意一行满足「当前行绝育状态为0、前一行绝育状态为1」的情况,即可判定该犬只存在错误反转。
对应R实现代码如下,400万行数据用dplyr可正常处理:
library(dplyr) library(lubridate) # 计算异常犬只列表 abnormal_dogs <- df_test %>% arrange(Idx, YEAR_date) %>% group_by(Idx) %>% # 取上一行的绝育状态,首行默认和自身值相等 mutate(prev_sterilized = lag(Is_sterilized, default = first(Is_sterilized))) %>% # 筛选出1→0的反转记录 filter(Is_sterilized < prev_sterilized) %>% distinct(Idx) %>% pull(Idx) # 打印异常犬只数量 cat("异常反转犬只数量:", length(abnormal_dogs))
你提供的示例数据运行后,得到的异常犬只为c("B","D"),和你标注的结果完全一致。
问题2:异常数据清理方案
可根据你的业务需求二选一:
- 方案1:直接剔除所有存在反转的犬只全部记录
适合对数据准确性要求极高,不愿引入修正误差的场景:
df_clean <- df_test %>% filter(!Idx %in% abnormal_dogs)
- 方案2:修正错误状态保留所有正常数据
绝育是不可逆操作,只要某只犬任意时间点出现过已绝育标识,后续所有记录的状态都应为1,用累积最大值函数可一键修正,不需要删除有效数据:
df_clean <- df_test %>% arrange(Idx, YEAR_date) %>% group_by(Idx) %>% # 累积最大值:只要出现过1,后续所有值都为1,完美匹配业务逻辑 mutate(Is_sterilized = cummax(Is_sterilized)) %>% ungroup()
附:清洗后新增绝育犬只统计代码
annual_new_sterilized <- df_clean %>% group_by(Idx) %>% # 取首次出现绝育标识的年份 filter(Is_sterilized == 1) %>% summarise(sterilize_year = min(year(YEAR_date))) %>% ungroup() %>% # 按年统计新增数量 count(sterilize_year, name = "new_sterilized_count")
若400万行数据处理性能不足,可改用
data.table包改写上述逻辑,速度会提升3-5倍,需要对应代码可直接说明。
内容的提问来源于stack exchange,提问作者TaL
相关产品推荐
相关产品推荐

