按患者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
相关产品推荐
相关产品推荐

