You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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()

逻辑说明

  1. 死亡组的累积计数:通过rev(cumsum(rev(fate == "Dead")))实现,把每个时间点之后的死亡数累加,这样当随访时间从720反向到1时,死亡数会从总死亡数逐渐减少到对应时间点的剩余死亡数
  2. 存活组固定计数:直接统计每个治疗组的存活总数,复制到所有随访时间点,保证动态过程中存活条形高度不变
  3. transition_time()比transition_reveal()更适合这种基于离散时间点的计数更新,配合reverse=TRUE完美实现反向播放需求

内容的提问来源于stack exchange,提问作者PTS390

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 07:50:25