Loess拟合后lines(lo)与predict(lo)结果差异的原因解析
为什么loess拟合后两种绘图方式结果不同?
嘿,这个问题我之前调试代码时也踩过坑!核心原因是lines()函数处理loess对象和直接传入拟合值向量时的逻辑完全不一样,具体拆解如下:
1. lines(lo)的绘图逻辑
当你把loess拟合对象直接传给lines()时,它会自动做一件事:先将拟合时的自变量(也就是你的df_raw$Scan)排序,再按排序后的顺序连接对应的拟合值。
本质上,它内部会调用predict.loess()获取拟合值,但同时会把自变量和拟合值按自变量从小到大排序,再绘制平滑线。这样画出来的线一定是沿着x轴递增方向平滑延伸的,不会出现来回跳转的情况。
2. lines(predict(lo))的绘图逻辑
predict(lo)返回的是和原始数据顺序完全一致的拟合值向量。当你直接把这个向量传给lines()时,它默认会用当前绘图窗口的x轴坐标(也就是df_raw$Scan的原始顺序)来对应这些拟合值。
如果你的df_raw$Scan不是单调递增/递减的(比如存在乱序、重复或者非连续的情况),那么线条就会跟着原始x的顺序来回连接,看起来就和lines(lo)的结果完全不同。
举个简单例子验证
假设你的df_raw$Scan是乱序的:
df_raw <- data.frame(Scan = c(3,1,2), `101` = c(5,2,3)) lo <- loess(df_raw$`101` ~ df_raw$Scan) # 第一种绘图 plot(df_raw$Scan, df_raw$`101`) lines(lo, col='red') # 会按x=1→2→3的顺序画拟合线 # 第二种绘图 plot(df_raw$Scan, df_raw$`101`) lines(predict(lo), col='blue') # 会按x=3→1→2的顺序画拟合线,线条是“跳着”的
解决办法:让两种绘图结果一致
如果想让lines(predict(lo))得到和lines(lo)一样的效果,只需要手动把自变量和拟合值按x排序后再绘图:
# 绑定自变量和拟合值,按x排序 fit_results <- data.frame(x = df_raw$Scan, y_fit = predict(lo)) fit_sorted <- fit_results[order(fit_results$x), ] # 绘图 plot(df_raw$Scan, df_raw$`101`) lines(fit_sorted$x, fit_sorted$y_fit, col='red', lwd=2)
当然,如果你的df_raw$Scan本来就是严格单调递增的,那两种绘图方式的结果会完全一致——问题就出在x轴变量无序的场景里!
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

