如何用R的dplyr包按60分钟区间分组计算value的中位数
用dplyr高效计算分时间区间的中位数
你需要对每个受试者按60分钟区间分组,计算对应区间内value的中位数,以下是替代重复filter和rbind的简洁dplyr实现方案:
数据准备(与你提供的一致)
library(dplyr) set.seed(1) df <- data.frame(id = c(rep("id1", 100), rep("id2", 100), rep("id3", 100)), value = runif(300, 10, 20)) %>% dplyr::group_by(id) %>% dplyr::mutate(cum_time = 5 * (dplyr::row_number()-1))
核心解决方案
通过生成区间终点分组,再按受试者ID和区间计算中位数:
result <- df %>% # 为每个时间点匹配对应的60分钟区间终点 mutate(interval_end = ceiling(cum_time / 60) * 60) %>% # 保留300分钟以内的区间(与目标结果一致) filter(interval_end <= 300) %>% # 按ID和区间终点分组 group_by(id, interval_end) %>% # 计算分组中位数 summarise(median_value = median(value), .groups = "drop") %>% # 重命名列名以匹配需求 rename(cum_time = interval_end) # 查看结果 print(result)
结果验证
运行代码后得到的结果与你手动计算的完全一致:
# A tibble: 15 × 3 id cum_time median_value <chr> <dbl> <dbl> 1 id1 60 15.7 2 id1 120 15.7 3 id1 180 14.9 4 id1 240 16.0 5 id1 300 14.6 6 id2 60 16.0 7 id2 120 14.7 8 id2 180 15.4 9 id2 240 15.2 10 id2 300 13.9 11 id3 60 12.7 12 id3 120 15.8 13 id3 180 14.0 14 id3 240 14.3 15 id3 300 15.1
方案说明
ceiling(cum_time / 60) * 60:利用向上取整,将每个时间点映射到对应60分钟区间的终点(如0-60分钟对应终点60,65-120分钟对应终点120),由于你的cum_time是5的倍数,不会出现落在区间间隙的数值,该方法完全适用。.groups = "drop":分组计算后自动取消分组,避免后续操作的分组干扰。- 全程通过dplyr链式操作完成,代码简洁易维护,可快速扩展到其他时间区间需求。
内容的提问来源于stack exchange,提问作者dan
相关产品推荐
相关产品推荐

