如何在ggplot2中添加不同带宽的核平滑非参数回归曲线?
没问题,我来教你怎么在ggplot2里添加这些非参数回归曲线!其实核心是把locpoly()的结果转换成ggplot能识别的数据框格式,然后用geom_line()添加进去就行,具体步骤和完整可运行代码如下:
完整解决方案代码
library(KernSmooth) library(ggplot2) # 1. 生成原始数据(和你原来的代码一致) set.seed(1995) X <- runif(100, -1, 1) G <- X[which(X > 0)] L <- X[which(X < 0)] u <- rnorm(100, 0, 0.02) Y <- -exp(-20*L^2)-exp(-20*G^2)/(X+1)+u # 2. 计算回归模型(线性+不同带宽的非参数回归) m <- lm(Y~X) m2 <- locpoly(X, Y, bandwidth = 0.05, degree = 0) m3 <- locpoly(X, Y, bandwidth = 0.15, degree = 0) m4 <- locpoly(X, Y, bandwidth = 0.3, degree = 0) # 3. 把非参数回归结果转换成ggplot可用的数据框 # 批量处理并合并不同带宽的结果,添加分组标识 non_param_df <- do.call(rbind, lapply( list("NW(bw=0.05)" = m2, "NW(bw=0.15)" = m3, "NW(bw=0.3)" = m4), function(model) { df <- as.data.frame(model) df$bandwidth <- names(model) df } )) # 4. 用ggplot绘制完整图形 ggplot(data.frame(X = X, Y = Y), aes(x = X, y = Y)) + # 绘制散点 geom_point(shape = 1) + # 添加线性回归曲线 geom_smooth(method = lm, se = FALSE, color = "red") + # 添加非参数回归曲线,按带宽分组设置颜色 geom_line(data = non_param_df, aes(x = x, y = y, color = bandwidth), linetype = 1) + # 手动指定曲线颜色,和你base R的设置一致 scale_color_manual(values = c( "NW(bw=0.05)" = "red", "NW(bw=0.15)" = "black", "NW(bw=0.3)" = "green" )) + # 你的自定义坐标轴样式 theme(axis.line = element_line(colour = "black", size = 0.25)) + # 优化图例标题 labs(color = "Non-parametric Regression")
关键细节说明
- 数据格式转换:
locpoly()返回的是包含x和y的列表,必须转换成数据框才能被ggplot使用。这里用批量处理的方式把三个带宽的结果合并成一个带bandwidth分组列的数据框,比手动创建三个数据框更高效。 - 修正数据源问题:你原来的ggplot代码用
lm对象作为数据源是不对的,ggplot需要原始的X/Y数据来绘制散点,所以这里用data.frame(X = X, Y = Y)作为主数据源。 - 自动分组与图例:通过
aes(color = bandwidth)让ggplot自动区分不同带宽的曲线,并生成对应的图例,无需手动添加多个geom_line。
内容的提问来源于stack exchange,提问作者User 6683331




