R语言如何按name分组批量查找数据集暴露峰值
问题原因
你之前尝试直接把name传入rleid()没有得到预期结果,核心是rleid()默认对整表按行顺序生成连续段ID,没有在单个个体的维度内独立计算连续暴露段,导致不同个体的暴露段被串连标记。
可行方案
只需要在计算连续段ID、聚合峰值时先按name分组,让所有峰值计算逻辑在每个个体的子集内独立执行即可,不需要逐次filter单个个体。
注意:你提供的示例数据构造代码存在类型问题:
cbind()拼接字符型name和数值型exposure时,会把exposure强制转为字符型,计算前需要先转回数值型避免报错。
data.table 实现(和你原有代码逻辑完全兼容)
library(data.table) # 转换全量数据为data.table格式,修正字段类型 setDT(data_all) data_all[, exposure := as.numeric(exposure)] # 按个体分组,组内独立标记连续有效暴露段(暴露值>=1的连续序列) data_all[, group := rleid(exposure >= 1), by = name] # 聚合得到所有个体的全量峰值信息 peak_info_all <- data_all[exposure >= 1, .(peak_height = max(exposure), peak_start = min(time_min), peak_end = max(time_min)), by = .(name, group)]
dplyr 实现(如果更习惯管道语法)
library(dplyr) library(data.table) # 调用rleid函数做连续段标记 peak_info_all <- data_all %>% mutate(exposure = as.numeric(exposure)) %>% group_by(name) %>% # 按个体分组后再标记连续段,避免跨个体串号 mutate(group = rleid(exposure >= 1)) %>% filter(exposure >= 1) %>% group_by(name, group) %>% summarise( peak_height = max(exposure), peak_start = min(time_min), peak_end = max(time_min), .groups = "drop" )
逻辑说明
- 分组计算
rleid()时,每个个体的连续段ID会独立从1开始计数,不会出现不同个体的暴露段被标记为同一个group的问题 - 最终输出结果会保留
name字段,你可以直接拿到所有个体每一段暴露的峰值高度、峰值开始时间、峰值结束时间,和你单独筛选单个个体计算的结果完全一致。
内容的提问来源于stack exchange,提问作者Miquel Vallbona
相关产品推荐
相关产品推荐

