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

基于两列去重并保留最新created_at记录的R语言实现

问题:按分组保留最新记录

现有R语言数据框,其中year(整数型)与legal_entity_registration_number(整数型)构成的组合存在重复记录,需依据created_at(日期时间格式)字段,保留每组重复数据中最新的一条完整记录。使用duplicated()函数仅能筛选重复观测,无法直接实现保留全列并提取最新记录的需求,以下是原始数据、期望结果及可行解决方案。

原始数据框

df <- structure(list(
  file_id = c(20045467L, 20057886L, 21624801L, 21624810L, 14889735L, 14889737L),
  legal_entity_registration_number = c(40003032949, 40003032949, 40003032949, 40003032949, 40003032949, 40003032949),
  year = c(2017L, 2017L, 2018L, 2018L, 2008L, 2008L),
  employees = c(1431L, 3908L, 1355L, 3508L, 1380L, 5378L),
  currency = c("EUR", "EUR", "EUR", "EUR", "LVL", "LVL"),
  rounded_to_nearest = c("THOUSANDS", "THOUSANDS", "THOUSANDS", "THOUSANDS", "ONES", "ONES"),
  created_at = structure(c(1604730505, 1604732566, 1605357231, 1605357235, 1597335737, 1609340436), 
                         class = c("POSIXct", "POSIXt"), tzone = "")
), row.names = c(NA, 6L), class = "data.frame")

期望结果数据框

expected_df <- structure(list(
  file_id = c(14889737L, 20057886L, 21624810L),
  legal_entity_registration_number = c(40003032949, 40003032949, 40003032949),
  year = c(2008L, 2017L, 2018L),
  employees = c(5378L, 3908L, 3508L),
  currency = c("LVL", "EUR", "EUR"),
  rounded_to_nearest = c("ONES", "THOUSANDS", "THOUSANDS"),
  created_at = structure(c(1609340436, 1604732566, 1605357235), 
                         tzone = "", class = c("POSIXct", "POSIXt"))
), class = c("grouped_df", "tbl_df", "tbl", "data.frame"), 
row.names = c(NA, -3L), 
groups = structure(list(
  year = c(2008L, 2017L, 2018L),
  legal_entity_registration_number = c(40003032949, 40003032949, 40003032949),
  .rows = structure(list(1L, 2L, 3L), ptype = integer(0), class = c("vctrs_list_of", "vctrs_vctr", "list"))
), row.names = c(NA, -3L), class = c("tbl_df", "tbl", "data.frame"), .drop = TRUE))

可行解决方案

方法1:使用tidyverse(dplyr)

这是最直观的方案,通过分组+排序+取首行实现:

library(dplyr)

result_df <- df %>%
  # 按分组列分组
  group_by(year, legal_entity_registration_number) %>%
  # 按created_at降序排列,最新记录排在每组最前面
  arrange(desc(created_at), .by_group = TRUE) %>%
  # 取每组第一行
  slice_head(n = 1) %>%
  # 可选:取消分组(如果不需要保留分组属性)
  ungroup()

或者更简洁的写法,直接用slice_max取每组最大的created_at对应的行:

result_df <- df %>%
  group_by(year, legal_entity_registration_number) %>%
  slice_max(created_at, n = 1) %>%
  ungroup()

方法2:使用Base R

无需加载额外包,通过排序+去重实现:

# 先按分组列升序,再按created_at降序排序
sorted_df <- df[order(df$year, df$legal_entity_registration_number, -df$created_at), ]
# 保留每组的第一条记录(即最新记录),去掉后续重复的分组组合
result_df <- sorted_df[!duplicated(sorted_df[c("year", "legal_entity_registration_number")]), ]

两种方法都能得到与期望结果一致的输出,保留所有列且仅保留每组最新记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 01:31:08