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

R语言分组聚合:如何保留其他列并获取起止日期极值?

按ID分组获取起止日期及关联列的实现方法

数据背景

假设存在如下R语言dataframe:

df <- data.frame(id = c(1,1,1,2,2,2,3,3,3,3),
             col1 = c("a","a", "b", "c", "d", "e", "f", "g", "h", "g"),
             start_day = c(NA,1,15, NA, 4, 22, 5, 11, 14, 18),
             end_day = c(NA,2, 15, NA, 6, 22, 6, 12, 16, 21))

输出结果为:

id col1 start_day end_day
1   1    a        NA      NA
2   1    a         1       2
3   1    b        15      15
4   2    c        NA      NA
5   2    d         4       6
6   2    e        22      22
7   3    f         5       6
8   3    g        11      12
9   3    h        14      16
10  3    g        18      21

需求说明

按唯一id分组,获取start_day列的最小值、end_day列的最大值,同时保留对应的关联列(如col1),最终得到包含col1_start(对应最小start_day的col1值)和col1_end(对应最大end_day的col1值)的结果。直接使用group_by()+summarise()会丢失col1列,无法满足需求。

解决方案

方法1:用dplyr的slice_min/slice_max拆分合并

分别提取每个组中start_day最小、end_day最大的行,再通过ID合并结果:

library(dplyr)

# 提取每组最小start_day对应的行
min_start_df <- df %>%
  group_by(id) %>%
  slice_min(start_day, na_rm = TRUE, with_ties = FALSE) %>%
  select(id, col1_start = col1, min_start_day = start_day)

# 提取每组最大end_day对应的行
max_end_df <- df %>%
  group_by(id) %>%
  slice_max(end_day, na_rm = TRUE, with_ties = FALSE) %>%
  select(id, col1_end = col1, max_end_day = end_day)

# 合并两个结果
final_result <- inner_join(min_start_df, max_end_df, by = "id")

最终输出:

id col1_start min_start_day col1_end max_end_day
  <dbl> <chr>              <dbl> <chr>          <dbl>
1     1 a                      1 b                 15
2     2 d                      4 e                 22
3     3 f                      5 g                 21

方法2:用dplyr的mutate标记后筛选

在组内标记出符合条件的行,再通过summarise整理目标列:

library(dplyr)

final_result <- df %>%
  group_by(id) %>%
  mutate(
    is_min_start = start_day == min(start_day, na.rm = TRUE),
    is_max_end = end_day == max(end_day, na.rm = TRUE)
  ) %>%
  filter(is_min_start | is_max_end) %>%
  summarise(
    col1_start = col1[is_min_start],
    min_start_day = start_day[is_min_start],
    col1_end = col1[is_max_end],
    max_end_day = end_day[is_max_end]
  ) %>%
  ungroup()

该方法结果与方法1完全一致。

方法3:用data.table快速实现

如果习惯使用data.table,可通过分组计算直接提取对应值:

library(data.table)
setDT(df)

final_result <- df[, .(
  col1_start = col1[which.min(start_day)],
  min_start_day = min(start_day, na.rm = TRUE),
  col1_end = col1[which.max(end_day)],
  max_end_day = max(end_day, na.rm = TRUE)
), by = id]

内容的提问来源于stack exchange,提问作者Joe the Second

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 23:09:23