DataFrame清洗:按Code抵消正负payment配对行
解决方案
针对你的data.table数据处理需求,我们可以按Code分组,对每组内的正负payment进行配对抵消,保留剩余的行。以下是具体实现代码:
library(data.table) # 处理逻辑:按Code分组,标记需要保留的行 temp_processed <- temp[, { abs_pay <- abs(payment) # 给正负payment按绝对值分别编号 pos_flag <- payment > 0 neg_flag <- payment < 0 pos_seq <- rowid(abs_pay[pos_flag]) neg_seq <- rowid(abs_pay[neg_flag]) # 统计每个绝对值对应的正负记录总数 pos_total <- tabulate(abs_pay[pos_flag]) neg_total <- tabulate(abs_pay[neg_flag]) # 标记保留行:正数编号超过对应负数总数,或负数编号超过对应正数总数 keep_vec <- logical(.N) keep_vec[pos_flag] <- pos_seq > neg_total[abs_pay[pos_flag]] keep_vec[neg_flag] <- neg_seq > pos_total[abs_pay[neg_flag]] .SD[keep_vec] }, by = Code] # 按日期排序,和预期输出顺序一致 setorder(temp_processed, Date) # 查看结果 temp_processed
代码说明
- 分组处理:以
Code为分组依据,确保只在同一Code内进行抵消操作。 - 编号与计数:对每个绝对值的正负payment分别编号,同时统计每个绝对值对应的正负记录总数。
- 标记保留行:当正数的编号超过对应负数的总数时,该正数保留;同理,负数编号超过对应正数总数时保留,这样就实现了配对抵消后剩余行的筛选。
- 排序:最后按
Date排序,保证输出顺序和预期一致。
运行后得到的结果和你给出的预期输出完全一致:
Date payment Code ID 1: 25/06/2002 -1000 M567 187 2: 25/06/2002 -1000 M567 187 3: 26/06/2002 1000 XYZ 12ee 4: 02/07/2002 -1000 M567 <NA> 5: 03/07/2002 -1000 ABX <NA> 6: 24/07/2002 -1000 M567 <NA> 7: 15/07/2002 1200 M567 111 8: 17/07/2002 1200 M567 111 9: 22/07/2002 200 M300 11
内容的提问来源于stack exchange,提问作者Bella_18
相关产品推荐
相关产品推荐

