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

如何在X轴为日期的ggplot时间序列图中添加线性回归平滑趋势线

解决方案

问题原因

你当前无法直接添加线性趋势线的核心原因是:X轴通过reorder(dates, value)将字符型日期转换为了有序分类因子,而线性回归lm()要求自变量为数值类型,直接使用y~x无法适配分类变量。

方案1:不改动现有X轴逻辑,直接适配

直接在stat_smooth中把X轴映射转换为数值型即可,无需修改原有绘图逻辑:

ggplot()+ 
  geom_line(data=combined,aes(x=reorder(dates,value),y=value,color=variable,group=variable))+
  # 新增线性趋势线代码
  stat_smooth(data=combined, aes(x=as.numeric(reorder(dates,value)), y=value, color=variable, group=variable),
              method = "lm", formula = y~x, se = FALSE)+
  scale_y_continuous(labels=function(x) format(x,scientific=FALSE))+
  theme_gray()+
  theme(axis.text.x = element_text(angle=90),
        plot.title=element_text(hjust=0.5),plot.subtitle = 
          element_text(hjust = 0.5))+
  annotate(geom = 'text',x='03.5.20',y=150000,label=
             'WHO declares Covid-19 a Pandemic')+
  annotate(geom = 'point',x='03.11.20',y=125865,size=6,shape=21,fill='blue')+
  labs(title='Cases in China vs World ',x='Daily trend from January to March',y='Case Numbers ',
       subtitle = 'Data From Jan 22,2020 - Mar 23,2020')

参数说明:

  • as.numeric(reorder(dates,value)):将有序因子转换为1、2、3...的时序数值,适配线性回归的自变量要求
  • se=FALSE可关闭置信区间填充,需要保留可以删掉这个参数
  • 保留color=variable和group=variable会自动为中国、全球各生成一条独立的趋势线

方案2:更规范的日期类型转换(推荐)

把字符型日期转换为R原生的日期类型,无需手动reorder排序,后续的标注、轴调整也更灵活:
第一步先处理数据集:

# 转换日期格式,%m代表月,%d代表日,%y代表两位年份
combined$dates <- as.Date(combined$dates, format = "%m.%d.%y")

然后修改绘图代码,X轴直接用日期变量,直接加stat_smooth即可:

ggplot()+ 
  geom_line(data=combined,aes(x=dates,y=value,color=variable,group=variable))+
  # 直接添加趋势线,无需额外转换
  stat_smooth(data=combined, aes(x=dates, y=value, color=variable, group=variable),
              method = "lm", formula = y~x, se = FALSE)+
  scale_y_continuous(labels=function(x) format(x,scientific=FALSE))+
  # 可以保留日期轴的倾斜设置
  scale_x_date(date_labels = "%m.%d.%y") +
  theme_gray()+
  theme(axis.text.x = element_text(angle=90),
        plot.title=element_text(hjust=0.5),plot.subtitle = 
          element_text(hjust = 0.5))+
  # 日期类的标注直接用Date类型值,不会出错
  annotate(geom = 'text',x=as.Date("2020-03-05"),y=150000,label=
             'WHO declares Covid-19 a Pandemic')+
  annotate(geom = 'point',x=as.Date("2020-03-11"),y=125865,size=6,shape=21,fill='blue')+
  labs(title='Cases in China vs World ',x='Daily trend from January to March',y='Case Numbers ',
       subtitle = 'Data From Jan 22,2020 - Mar 23,2020')

可选优化提示

新冠病例数属于指数增长特征的数据,线性回归拟合的直线会和实际曲线偏差较大,如果需要更贴合的平滑趋势,可以把method="lm"换成method="loess",或者对y值做对数转换后再拟合线性模型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 16:54:02