基于gganimate制作反向随随访时间递减的动态条形图
完善动态条形图实现逻辑
你的核心需求是仅让死亡人群的计数随反向随访时间递减,存活人群计数保持不变,原代码用transition_reveal()的问题在于没有区分两类人群的逻辑,且直接对原始计数做过渡,无法实现针对性的递减效果。以下是修正后的实现方案:
步骤1:数据预处理
首先需要拆分存活/死亡人群,分别处理计数逻辑:
- 存活人群:每个治疗组的存活数是固定值,无需随随访时间变化
- 死亡人群:按随访时间升序排序后,计算每个时间点及之后的累积死亡数(反向播放时,相当于从最长随访时间到最短,死亡数逐渐减少,模拟"去掉早死亡案例"的效果)
library(tidyverse) library(pubh) library(gganimate) # 预处理数据 processed_data <- Bernard %>% select(fate, treat, followup) %>% # 处理死亡组:计算每个时间点的累积死亡数(从当前时间到最大时间的死亡数) group_by(treat, fate) %>% mutate( # 仅对死亡组计算累积计数 count = if_else(fate == "Dead", rev(cumsum(rev(fate == "Dead"))), NA_real_) ) %>% ungroup() %>% # 处理存活组:每个治疗组的存活数固定 group_by(treat) %>% mutate( count = if_else(fate == "Alive", sum(fate == "Alive"), count) ) %>% ungroup() %>% # 去重并整理结构,确保每个时间点都有存活/死亡的计数 distinct(treat, fate, followup, count) %>% arrange(treat, fate, followup)
步骤2:绘制动态条形图
使用transition_time()配合reverse=TRUE实现反向播放,用geom_col()基于预处理后的计数绘图,确保存活组高度不变,死亡组随时间递减:
ggplot(processed_data, aes(x = treat, y = count, fill = fate)) + geom_col(position = "stack") + # 反向播放随访时间,从720小时到1小时 transition_time(followup) + ease_aes("linear") + # 平滑过渡效果 labs( title = "随访时间: {round(frame_time, 0)} 小时", x = "治疗方案", y = "人数", fill = "结局" ) + theme_minimal()
逻辑说明
- 死亡组的累积计数:通过
rev(cumsum(rev(fate == "Dead")))实现,把每个时间点之后的死亡数累加,这样当随访时间从720反向到1时,死亡数会从总死亡数逐渐减少到对应时间点的剩余死亡数 - 存活组固定计数:直接统计每个治疗组的存活总数,复制到所有随访时间点,保证动态过程中存活条形高度不变
transition_time()比transition_reveal()更适合这种基于离散时间点的计数更新,配合reverse=TRUE完美实现反向播放需求
内容的提问来源于stack exchange,提问作者PTS390
相关产品推荐
相关产品推荐

