在ggplot2中为多种拟合模型添加R²与方程并批量绘图
解决方法:为四种拟合模型添加方程与R²,及纯ggplot2实现方案
一、为所有模型添加方程和R²
不用局限于ggpmisc的默认函数,我们可以自定义函数提取模型参数、生成格式化的方程与R²文本,再结合ggplot2的标注图层完成添加。
1. 定义模型参数提取函数
针对线性、对数、指数、幂四种模型,分别编写拟合并生成文本的函数:
# 线性模型:y = ax + b get_lm_eq <- function(x, y) { model <- lm(y ~ x) a <- coef(model)[[2]] b <- coef(model)[[1]] r2 <- summary(model)$r.squared sprintf("线性:y=%.2fx+%.2f\nR²=%.3f", a, b, r2) } # 对数模型:y = a*ln(x) + b get_log_eq <- function(x, y) { model <- lm(y ~ log(x)) a <- coef(model)[[2]] b <- coef(model)[[1]] r2 <- summary(model)$r.squared sprintf("对数:y=%.2fln(x)+%.2f\nR²=%.3f", a, b, r2) } # 指数模型:y = b*e^(ax)(转换为线性拟合ln(y) = ax + ln(b)) get_exp_eq <- function(x, y) { model <- lm(log(y) ~ x) a <- coef(model)[[2]] b <- exp(coef(model)[[1]]) r2 <- summary(model)$r.squared sprintf("指数:y=%.2fe^(%.2fx)\nR²=%.3f", b, a, r2) } # 幂模型:y = b*x^a(转换为线性拟合ln(y) = a*ln(x) + ln(b)) get_power_eq <- function(x, y) { model <- lm(log(y) ~ log(x)) a <- coef(model)[[2]] b <- exp(coef(model)[[1]]) r2 <- summary(model)$r.squared sprintf("幂:y=%.2fx^%.2f\nR²=%.3f", b, a, r2) }
2. 循环绘图时添加标注
假设你的晶体数据集列表为crystal_datasets,每个数据集包含x和y列,循环绘图代码如下:
library(ggplot2) for (data in crystal_datasets) { # 计算四个模型的标注文本 lm_text <- get_lm_eq(data$x, data$y) log_text <- get_log_eq(data$x, data$y) exp_text <- get_exp_eq(data$x, data$y) power_text <- get_power_eq(data$x, data$y) # 绘制曲线与标注 p <- ggplot(data, aes(x, y)) + geom_point(size=2, color="black") + # 四种拟合曲线 geom_smooth(method="lm", formula=y~x, color="red", se=FALSE) + geom_smooth(method="lm", formula=y~log(x), color="blue", se=FALSE) + geom_smooth(method="nls", formula=y~b*exp(a*x), start=list(a=0.1, b=1), color="green", se=FALSE) + geom_smooth(method="nls", formula=y~b*x^a, start=list(a=1, b=1), color="purple", se=FALSE) + # 添加各模型的方程与R²,通过位置参数避免重叠 geom_label(x=min(data$x), y=max(data$y), label=lm_text, hjust=0, vjust=1, fill="red", alpha=0.8) + geom_label(x=min(data$x), y=max(data$y)*0.8, label=log_text, hjust=0, vjust=1, fill="blue", alpha=0.8) + geom_label(x=min(data$x), y=max(data$y)*0.6, label=exp_text, hjust=0, vjust=1, fill="green", alpha=0.8) + geom_label(x=min(data$x), y=max(data$y)*0.4, label=power_text, hjust=0, vjust=1, fill="purple", alpha=0.8) + theme_bw() print(p) }
二、能否仅依靠ggplot2实现?
可以。ggplot2本身没有内置生成非线性模型方程与R²的函数,但所有逻辑都可以手动完成:用geom_smooth()绘制四种拟合曲线,自己编写函数完成模型拟合、参数提取和文本格式化,再通过geom_text()或geom_label()添加标注,全程无需依赖ggpmisc或其他第三方包。
注意:使用geom_smooth(method="nls")绘制指数、幂模型时,必须指定合理的初始参数start,否则可能出现拟合失败的情况。
内容的提问来源于stack exchange,提问作者murpholinox
相关产品推荐
相关产品推荐

