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

ggplot2中geom_line()的Aesthetics长度不匹配报错求解

问题描述

我正在为大学课程绘制比利时2009-2022年每周推断超额死亡率图(分2019年前及2020年后),运行ggplot2代码时触发以下错误:

Error in geom_line(): ! Problem while computing aesthetics. ℹ Error occurred in the 1st layer. Caused by error in check_aesthetics(): ! Aesthetics must be either length 1 or the same as the data (2296) ✖ Fix the following mappings: y

尝试过Statology网站的解决方案但无效,期望实现按年份着色,附上代码请求帮助。

问题代码
ggplot(data=preds[preds$YEAR<=2019,], aes(x=as.numeric(as.character(WEEK)), y=1E7*preds$excess_deaths/POPULATION), colour = factor(YEAR)) +
  geom_line(aes(y=1E7*preds$excess_deaths/POPULATION, colour = NA)) +
  geom_ribbon(data=preds[preds$YEAR<=2019,], aes(ymin=1E7*preds$lower.CI/POPULATION, ymax=1E7*preds$upper.CI/POPULATION), colour=NA, alpha=I(0.4)) + 
  geom_ribbon(aes(ymin=1E7*preds$excess_deaths.lower.PI/POPULATION, ymax=1E7*preds$excess_deaths.upper.PI/POPULATION), colour=NA, alpha=I(0.2)) + 
  geom_line(data=preds[preds$YEAR>=2020,], aes(y=1E7*preds$excess_deaths/POPULATION, colour = NA)) +
  geom_ribbon(data=preds[preds$YEAR>=2020,], 
              aes(ymin=1E7*preds$excess_deaths.lower.CI/POPULATION, ymax=1E7*preds$excess_deaths.upper.CI/POPULATION), colour=NA, alpha=I(0.4)) + 
  geom_ribbon(data=preds[preds$YEAR>=2020,], 
              aes(ymin=1E7*preds$excess_deaths.lower.PI/POPULATION, ymax=1E7*preds$excess_deaths.upper.PI/POPULATION), colour=NA, alpha=I(0.2)) + 
  facet_wrap(~ model, ncol = 1) +
  xlab("Date") +
  ylab("Excess mortality (Per 10M inhabitants") +
  ggtitle(label = 'EXCESS MORTALITY IN BELGIUM PER WEEK (PER 10M INHABITANTS)', subtitle = 'Data Statbel 2009-2022') +
  theme_economist_white()
错误核心原因

代码中所有aes()映射里的y值、区间边界都直接引用了全局数据框preds$xxx,而非当前图层子集数据的列。比如第一个ggplot()指定了data=preds[preds$YEAR<=2019,](子集长度2296),但aes(y=1E7*preds$excess_deaths/POPULATION)用的是全量数据,长度远大于2296,导致美学映射长度不匹配,触发错误。

修正方案

1. 提前预处理数据(简化代码+避免重复计算)

先计算好标准化后的超额死亡率及各类区间值,减少绘图代码中的复杂计算:

# 需先加载dplyr包
library(dplyr)

preds <- preds %>%
  mutate(
    # 标准化到每1000万居民的超额死亡率
    excess_std = 1E7 * excess_deaths / POPULATION,
    # 置信区间标准化
    lower_ci_std = 1E7 * lower.CI / POPULATION,
    upper_ci_std = 1E7 * upper.CI / POPULATION,
    # 预测区间标准化
    lower_pi_std = 1E7 * excess_deaths.lower.PI / POPULATION,
    upper_pi_std = 1E7 * excess_deaths.upper.PI / POPULATION
  )

2. 修正后的绘图代码

ggplot(data = preds, aes(x = as.numeric(as.character(WEEK)), y = excess_std, colour = factor(YEAR))) +
  # 2009-2019年的线与区间
  geom_line(data = preds[preds$YEAR <= 2019,]) +
  geom_ribbon(data = preds[preds$YEAR <= 2019,], 
              aes(ymin = lower_ci_std, ymax = upper_ci_std), 
              colour = NA, alpha = 0.4, fill = "grey70") +
  geom_ribbon(data = preds[preds$YEAR <= 2019,], 
              aes(ymin = lower_pi_std, ymax = upper_pi_std), 
              colour = NA, alpha = 0.2, fill = "grey80") +
  
  # 2020-2022年的线与区间
  geom_line(data = preds[preds$YEAR >= 2020,]) +
  geom_ribbon(data = preds[preds$YEAR >= 2020,], 
              aes(ymin = lower_ci_std, ymax = upper_ci_std), 
              colour = NA, alpha = 0.4, fill = "#4292c6") +
  geom_ribbon(data = preds[preds$YEAR >= 2020,], 
              aes(ymin = lower_pi_std, ymax = upper_pi_std), 
              colour = NA, alpha = 0.2, fill = "#9ecae1") +
  
  facet_wrap(~ model, ncol = 1) +
  labs(
    x = "日期",
    y = "超额死亡率(每1000万居民)",
    title = "比利时每周推断超额死亡率(每1000万居民)",
    subtitle = "数据来源:Statbel 2009-2022",
    colour = "年份"
  ) +
  theme_economist_white()

关键修正点

  • 所有aes()映射直接使用预处理后的列名,不再引用全局preds$xxx,确保每个图层使用自身子集数据,长度匹配
  • 移除原代码中colour=NA的设置,保留colour = factor(YEAR)实现按年份着色的需求
  • 提前计算标准化值,简化绘图代码逻辑,减少出错概率
  • 给不同时间段的区间设置差异化填充色,提升图表可读性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 07:55:39