R语言for循环绘制标准化残差与拟合值图 实现多图同页展示
原代码核心问题
- 混用base R绘图函数
scatter.smooth和仅ggplot2支持的facet_wrap语法,两类绘图系统不兼容,无法实现分面排列效果 - 布局设置代码被注释且放在循环内部,每轮循环仅绘制单张图,无法实现多图同页
- 残差、拟合值提取逻辑放在循环内部,重复运行无意义,降低运行效率
- 用
attach()加载数据集容易引发环境变量冲突,不推荐使用
可行实现方案
方案1:base R原生实现(适配原有scatter.smooth写法)
无需额外安装绘图包,直接调整逻辑即可实现多图同页排列:
library(GLMsData) data(fluoro) lambda <- seq(-1, 1, 0.2) n_lambda <- length(lambda) lm.out <- vector("list", n_lambda) # 先完成所有模型拟合,统一提取残差和拟合值 for (i in 1:n_lambda) { if (lambda[i] != 0) { y <- (fluoro$Dose^lambda[i] - 1)/lambda[i] } else { y <- log(fluoro$Dose) } lm.out[[i]] <- lm(y ~ Time, data = fluoro, na.action = na.exclude) } SS <- sapply(lm.out, rstandard) FV <- sapply(lm.out, fitted) # 全局设置绘图布局:3行4列适配11张图,同步调整边距避免标签重叠 par(mfrow = c(3,4), mar = c(4,4,3,1)) for (i in 1:n_lambda) { scatter.smooth( SS[, i] ~ FV[, i], col = "grey", las = 1, ylab = "标准化残差", xlab = "拟合值", main = bquote(lambda == .(round(lambda[i],1))) ) } # 绘图完成后重置默认绘图参数 par(mfrow = c(1,1))
方案2:ggplot2实现(更美观的自动分面效果)
如果需要更灵活的样式调整,统一用ggplot2语法实现分面更便捷:
library(GLMsData) library(ggplot2) library(dplyr) data(fluoro) lambda <- seq(-1, 1, 0.2) # 批量拟合模型并整理为绘图长表 plot_data <- lapply(lambda, function(l){ y <- ifelse(l != 0, (fluoro$Dose^l - 1)/l, log(fluoro$Dose)) mod <- lm(y ~ Time, data = fluoro, na.action = na.exclude) data.frame( lambda = as.factor(round(l, 1)), fitted = fitted(mod), std_resid = rstandard(mod) ) }) %>% bind_rows() # 自动分面绘图 ggplot(plot_data, aes(x = fitted, y = std_resid)) + geom_point(color = "grey") + geom_smooth(method = "loess", se = FALSE, linewidth = 0.8) + facet_wrap(~lambda, ncol = 3) + labs(x = "拟合值", y = "标准化残差") + theme_bw()
内容的提问来源于stack exchange,提问作者Quamena
相关产品推荐
相关产品推荐

