如何用R(优先dplyr)基于分组数据生成带条件的CT和mTT新列
使用dplyr实现基于ID分组的条件列生成
需求说明
基于给定数据框,按ID分组,根据每个ID最后一个time对应的PT值,生成CT和mTT两个新列,规则如下:
- CT列:每行默认取
PT与180的最小值;若该ID最后一个PT值小于180,则该行CT设为180。 - mTT列:默认等于
TT;若该ID最后一个PT值小于180,则该行mTT = TT + (180 - PT)。
原始数据
data <- data.frame( ID = c(rep(91, 4), rep(92, 5), rep(95, 3), rep(90, 4)), time = c(1, 2, 3, 4, 1, 2, 3, 4, 5, 1, 2, 3, 1, 2, 3, 4), TT = c(rep(32, 4), rep(37, 5), rep(10, 3), rep(20, 4)), PT = c(245, 345, 100, 273, 270, 340, 240, 170, 80, 33, 230, 50, 85, 100, 200, 200) )
期望输出
result <- data.frame( ID = c(rep(91, 4), rep(92, 5), rep(95, 3), rep(90, 4)), time= c(1, 2, 3, 4, 1, 2, 3, 4, 5, 1, 2, 3, 1, 2, 3, 4), TT = c(rep(32, 4), rep(37, 5), rep(10, 3), rep(20, 4)), PT = c(245, 345, 100, 273, 270, 340, 240, 170, 80, 33, 230, 50, 85, 100, 200, 200), CT =c(180,180,100,180,180,180,180,170,180,33,180,180,85,100, 180,180), mTT= c(rep(32, 4), rep(37, 4),137, rep(10, 2),140, rep(20, 4)) )
dplyr解决方案
通过分组计算每个ID的最后一个PT值,再结合条件生成新列:
library(dplyr) output <- data %>% group_by(ID) %>% # 按time排序,确保取到正确的最后一个PT值 arrange(time, .by_group = TRUE) %>% # 计算每个ID的最后一个PT值 mutate(last_PT = last(PT)) %>% # 生成CT列 mutate(CT = ifelse(last_PT < 180, 180, pmin(PT, 180))) %>% # 生成mTT列 mutate(mTT = ifelse(last_PT < 180, TT + (180 - PT), TT)) %>% # 移除中间变量(可选) select(-last_PT) %>% ungroup() # 验证结果是否与期望一致 all.equal(output, result)
逻辑解释
- 分组排序:按
ID分组后,再按time排序,保证last(PT)获取的是该ID最后一个时间点的PT值。 - 计算分组标识值:用
last(PT)得到每个ID的最终PT值,作为后续条件判断的依据。 - 生成CT列:根据分组标识值判断,若最后一个PT小于180则CT设为180,否则取PT与180的最小值。
- 生成mTT列:同样根据分组标识值判断,若最后一个PT小于180则计算
TT + (180-PT),否则保留原TT值。 - 清理数据:移除中间变量并取消分组,得到最终结果。
内容的提问来源于stack exchange,提问作者AziR
相关产品推荐
相关产品推荐

