为多时间序列图添加趋势平滑线时缺失值报错问题咨询
我之前也碰到过类似的情况,咱们一步步拆解你的问题:
问题背景
你用gather把宽表转成适合ggplot的长表后,绘制分组面积图一切正常,但添加stat_smooth(method="loess")时,却持续出现「Removed 2 row(s) containing missing values (geom_path)」报错,还伴随奇异点、倒数条件类的错误,修改或删除数据都没解决。
核心原因分析
loess方法的局限性:
loess是局部加权回归,它需要每个局部窗口内有足够多的数据点才能稳定拟合。你的数据集时间点非常少(总共只有6个不同的日期,且间隔不均匀:7月有多个点,直接跳到9月、10月),局部窗口里的样本数严重不足,导致拟合过程中出现奇异矩阵、无法计算权重的问题,最终产生NA值,触发缺失值报错。position_dodge的错位问题:
你的面积图用了position_dodge(0.8)让两组数据错开显示,但stat_smooth默认是基于原始x(日期)值拟合整个数据集的趋势,没有跟着分组的错位位置走,这不仅会让平滑线和面积图位置不匹配,还会进一步加剧拟合的数据稀疏问题。
具体解决办法
方法1:换用更适合小数据的平滑方法
如果一定要保留平滑线,别用loess了,换成对小数据更友好的线性回归加多项式拟合,比如:
# 先重新定义p对象,把分组变量放到全局aes里 p <- ggplot(df, aes(x = date, y = value, color = variable, fill = variable)) + geom_area(alpha = 0.5, position = position_dodge(0.8)) + scale_color_manual(values = c("#00AFBB", "#E7B800")) + scale_fill_manual(values = c("#00AFBB", "#E7B800")) # 添加多项式拟合的平滑线,同时对齐dodge位置 p + stat_smooth(method = "lm", formula = y ~ poly(x, 2), position = position_dodge(0.8), color = "#FC4E07", fill = "#FC4E07")
方法2:调整loess的span参数(仅当数据略多时有用)
如果坚持要用loess,你可以增大span参数来扩大局部窗口的范围,让每个窗口包含更多数据点:
p + stat_smooth(color = "#FC4E07", fill = "#FC4E07", method = "loess", span = 1, # span值越大,窗口范围越宽 position = position_dodge(0.8))
不过你的数据点太少,这个方法可能效果还是有限。
方法3:检查并规范数据
确认数据中的0值是真实的0还是缺失值:如果是缺失值,把0替换成NA,ggplot会自动忽略这些值,但本质上还是解决不了数据量不足的问题,最好的办法还是补充更多时间点的观测数据。
内容的提问来源于stack exchange,提问作者Doug Mounce

