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

按患者ID分组聚合DataFrame:保留最小Start.Time与最大End.Time

问题描述

现有如下结构的DataFrame:

> dput(df)
structure(list(Person = c(123L, 123L, 123L), Start.Time = c("2023-06-18 12:22:00", 
"2023-06-18 10:22:00", "2023-06-18 06:22:00"), End.Time = c("2023-06-19 15:41:00", 
"2023-06-19 05:41:00", "2023-06-19 15:30:00")), class = "data.frame", row.names = c(NA, 
-3L))

需要按患者ID(Person字段)分组,每组仅保留一行核心数据(选取该组的最小Start.Time和最大End.Time),同时保持原数据的行数,其余行对应字段填充NA,期望结果如下:

> dput(df2)
structure(list(Person = c(123L, NA, NA), Start.Time = c("2023-06-18 06:22:00"), End.Time = c("2023-06-19 15:41:00")), class = "data.frame", row.names = c(NA, 
-3L))
解决方案

方法1:使用dplyr包(推荐)

先安装并加载dplyr,通过分组聚合得到核心结果后,再扩展为原行数并填充NA:

# 安装包(首次使用时执行)
# install.packages("dplyr")
library(dplyr)

# 分组聚合核心数据
agg_df <- df %>%
  group_by(Person) %>%
  summarise(
    Start.Time = min(Start.Time),
    End.Time = max(End.Time),
    .groups = "drop"
  )

# 扩展为原行数并填充重复值为NA
df_result <- agg_df %>%
  slice(rep(1:n(), each = nrow(df))) %>%
  mutate(
    Person = replace(Person, duplicated(Person), NA),
    Start.Time = replace(Start.Time, duplicated(Start.Time), NA),
    End.Time = replace(End.Time, duplicated(End.Time), NA)
  )

方法2:使用Base R

通过aggregate完成聚合,再手动构造符合要求的结果DataFrame:

# 分组聚合得到核心数据
agg_result <- aggregate(
  cbind(Start.Time, End.Time) ~ Person,
  data = df,
  FUN = function(col) {
    c(min(col), max(col))[c(1,2)] # 取最小和最大值
  }
)

# 构造期望格式的结果
df_result <- data.frame(
  Person = c(agg_result$Person, rep(NA, nrow(df)-1)),
  Start.Time = c(agg_result$Start.Time, rep(NA, nrow(df)-1)),
  End.Time = c(agg_result$End.Time, rep(NA, nrow(df)-1))
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 19:35:21