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

ggplot2甘特图:如何按降序排列日期轴并解决排序报错

问题

创建甘特图时,按升序日期排列可正常绘制,但希望遵循甘特图惯例,让y轴任务按x轴日期降序排列,使用降序排序时出现如下报错:

Error in geom_line():
! Problem while computing aesthetics.
ℹ Error occurred in the 1st layer.
Caused by error in -.Date:
! unary - is not defined for "Date" objects
Run rlang::last_error() to see where the error occurred.

原因分析

  1. 直接报错原因:reorder(Tasks,-value)中的value是Date类型,R不支持对Date对象使用一元负号(-)进行反转排序操作。
  2. 逻辑问题:数据经pivot_longer拆分后,每个任务对应start.date和end.date两个日期值,直接用value排序会导致任务排序逻辑混乱,应该基于任务的开始日期统一排序。

解决方案

修改要点

  • 在原始数据框中,按start.date降序定义Tasks的因子顺序,确保y轴任务按开始日期从晚到早排列。
  • 修正scale_x_date的语法错误(参数间缺少逗号)。

修改后的完整代码

## 创建数据框 ## 
gantt <- data.frame(
  Tasks = c('Refine analysis plan', 'Retrieve data', 'Identify cases using SNOMED codes and study start/end dates', 
            'Retrieve clinical and referral events', 'Retrieve covariate data',
            'Table of cohort characteristics and outcome frequencies','Age and gender distribution of incident cases (fig1)','Age and gender distribution of prevalent cases (fig2)',
            'Prepare and submit abstract','PPIE work 2',
            'Frequency of referrals (staff) (fig3)','Frequency of 2care referrals (staff) (fig4)','Frequency of 2care referrals (diagnosis category) (fig5)',
            'Descriptive paper draft for coauthor review',
            'Regression analysis of predictors 1',
            'Regression analysis of predictors 2',
            'Regression analysis of predictors 3',
            'Modelling paper draft for coauthor review','conference','Modelling paper draft for coauthor review',
            'Submit papers to BJGP','Respond to reviewer comments','PPIE work 3'),
  start.date = as.Date(c("2022-11-01", "2022-11-14", "2022-11-16",
                         "2022-11-18", "2022-12-01", 
                         "2023-01-02","2023-01-09","2023-01-19",
                         "2023-02-01","2023-02-16",
                         "2023-03-01", "2023-03-13", "2023-03-23",
                         "2023-04-03",
                         "2023-05-01", "2023-05-15", "2023-05-25",
                         "2023-06-01",
                         "2023-07-03","2023-07-18","2023-07-21",
                         "2023-08-01","2023-08-01")),
  end.date = as.Date(c("2022-11-14", "2022-11-16", "2022-11-17",
                       "2022-11-30", "2022-12-16", 
                       "2023-01-06","2023-01-18","2023-01-31",
                       "2023-02-15","2023-02-28",
                       "2023-03-10", "2023-03-22", "2023-03-31",
                       "2023-04-28",
                       "2023-05-12", "2023-05-24", "2023-05-30",
                       "2023-06-30",
                       "2023-07-17","2023-07-20","2023-07-31",
                       "2023-08-31","2023-08-31")),
  task_type = c("Planning","Data preparation","Data preparation",
                "Data preparation","Data preparation","Data description","Data visualisation",
                "Data visualisation","Dissemination & communication","Patient & public involvement and engagement",
                "Data visualisation","Data visualisation","Data visualisation",
                "Dissemination & communication","Data analysis/modelling","Data analysis/modelling","Data analysis/modelling",
                "Dissemination & communication","Dissemination & communication","Dissemination & communication",
                "Dissemination & communication","Dissemination & communication","Patient & public involvement and engagement")
)

gantt$duration <- gantt$end.date - gantt$start.date

# 关键修改:按start.date降序设置Tasks的因子顺序
gantt$Tasks <- factor(gantt$Tasks, levels = rev(gantt$Tasks[order(gantt$start.date)]), ordered = TRUE)

# 创建甘特图数据格式
mgantt <- gantt %>%
  tidyr::pivot_longer(col = c(start.date, end.date))

# 绘图:无需在aes中用reorder,直接使用已定义好顺序的Tasks
pl <- ggplot(mgantt, aes(x = value, y = Tasks, colour = task_type))
pl <- pl + geom_line(alpha = 0.5, size = 7)
pl <- pl + theme_bw()
pl <- pl + labs(title = "Gantt Chart", x = "Month", y = "Tasks")
pl <- pl + theme(legend.position = "bottom")
# 修正语法错误:添加参数间的逗号
pl <- pl + scale_x_date(
  name = "Month",
  date_labels = "%b%y",
  date_breaks = "1 month",
  minor_breaks = "1 day"
)
pl

说明

修改后,y轴任务会按照开始日期从晚到早排列,符合甘特图的常规展示方式,同时避免了Date对象的负号操作报错,也修正了原始代码中的语法问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 04:01:42