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
相关产品推荐
相关产品推荐

