You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于两个日期对DataFrame去重:按ID保留Date2与Date1最接近的行的实现方法

解决方法:按ID筛选Date2与Date1最接近的行

这问题我熟,咱们一步步来实现,保证每个ID只留一行,且是Date2和Date1日期差最小的那行~

首先要注意:你的Date1和Date2都是字符串格式,得先转换成R能识别的日期类型,不然没法计算日期差。下面给你两种常用的实现方式:

方法一:用dplyr包(推荐,代码更直观)

dplyr是处理数据框的常用工具包,代码逻辑清晰,容易理解:

# 先加载dplyr包,如果没安装先运行install.packages("dplyr")
library(dplyr)

# 处理数据:转换日期→分组→计算差值→筛选最小差值行→去重
df_processed <- df %>%
  # 把字符串日期转换成R的日期格式(注意是日/月/年,所以format用"%d/%m/%Y")
  mutate(
    Date1 = as.Date(Date1, format = "%d/%m/%Y"),
    Date2 = as.Date(Date2, format = "%d/%m/%Y")
  ) %>%
  # 按ID分组,后续操作都在每个ID组内进行
  group_by(ID) %>%
  # 计算Date2与Date1的绝对日期差(避免正负影响)
  mutate(date_diff = abs(Date2 - Date1)) %>%
  # 筛选出每个组中日期差最小的行
  filter(date_diff == min(date_diff)) %>%
  # 如果同一ID有多个行日期差相同,只保留第一行
  slice_head(n = 1) %>%
  # 去掉临时计算的date_diff列
  select(-date_diff) %>%
  # 取消分组,回到普通数据框
  ungroup()

# 查看结果
print(df_processed)

方法二:用Base R(无需额外加载包)

如果你不想加载第三方包,用Base R也能实现:

# 第一步:转换日期格式
df$Date1 <- as.Date(df$Date1, format = "%d/%m/%Y")
df$Date2 <- as.Date(df$Date2, format = "%d/%m/%Y")

# 第二步:计算每个行的绝对日期差
df$date_diff <- abs(df$Date2 - df$Date1)

# 第三步:找出每个ID组中日期差最小的行的索引
min_diff_idx <- ave(df$date_diff, df$ID, FUN = function(x) x == min(x)) == 1

# 第四步:筛选出这些行,并且每个ID只保留第一行
df_processed <- df[min_diff_idx, ]
df_processed <- df_processed[!duplicated(df_processed$ID), ]

# 第五步:去掉临时的date_diff列
df_processed$date_diff <- NULL

# 查看结果
print(df_processed)

验证结果

运行后你会看到:

  • ID=5的行,Date2是2014-07-22,和Date1完全相同,是最接近的;
  • ID=14的行,Date2是2015-05-14,和Date12016-11-08的日期差最小。

内容的提问来源于stack exchange,提问作者Lili

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 13:53:15