R语言按唯一ID筛选距指定日期最近的数据框子集
R语言按分组筛选距指定日期最近记录实现方法
你可以通过以下两种方案实现需求,核心逻辑为:先计算每条还款记录与预设日期的时间差,再按Loan_ID分组,保留每个分组下时间差最小的记录即可。本次场景预设参考日期为as.Date("2022-03-31")。
方法一:dplyr 实现(推荐,适合大数据量场景)
代码可读性强,处理百万级以上数据效率更高:
# 加载包,若未安装可先运行 install.packages("dplyr") library(dplyr) # 定义参考日期 ref_date <- as.Date("2022-03-31") result <- df %>% mutate( # 计算每条记录与参考日期的绝对天数差 day_gap = abs(as.numeric(difftime(Execution_Date, ref_date, units = "days"))) ) %>% group_by(Loan_ID) %>% # 保留组内天数差最小的记录 filter(day_gap == min(day_gap)) %>% # 删除临时计算的差值列 select(-day_gap) %>% ungroup()
运行后输出结果与预期完全匹配:
# A tibble: 2 × 3 Loan_ID Execution_Sum Execution_Date <dbl> <dbl> <date> 1 1 800 2022-03-17 2 2 400 2022-03-29
方法二:基础R实现,无需依赖第三方包
适合不想额外安装包的轻量场景:
# 定义参考日期 ref_date <- as.Date("2022-03-31") # 计算所有记录与参考日期的绝对天数差 df$day_gap <- abs(as.numeric(difftime(df$Execution_Date, ref_date, units = "days"))) # 按Loan_ID分组,筛选组内天数差最小的行 result <- df[ave(df$day_gap, df$Loan_ID, FUN = \(x) x == min(x)) == 1, ] # 移除临时生成的差值列 result$day_gap <- NULL
补充说明:如果同一
Loan_ID下存在多条记录与参考日期间隔完全相等,上述两种方法会默认保留所有匹配记录;如果需要每个ID强制仅返回1条记录,可在排序后取每个分组的第一行即可,例如dplyr中可在group_by后使用slice_max(order_by = Execution_Date, n =1)替换原有filter逻辑,直接取每个ID下最晚的还款记录即可。
内容的提问来源于stack exchange,提问作者lenpyspanacb
相关产品推荐
相关产品推荐

