如何在R语言中实现对数正态拟合曲线绘制及指定X轴范围?
R语言对数正态拟合与目标样式绘图
完整代码实现
# 加载用户提供的数据集 x_values <- c(40, 41, 42, 44, 45, 46, 48, 49, 51, 53, 54, 56, 58, 59, 61, 63, 65, 67, 69, 71, 73, 76, 78, 80, 83, 85, 88, 91, 94, 96, 99, 102, 106, 109, 112, 116, 119, 123, 127, 131, 135, 139, 143, 148, 152, 157, 162, 167, 172, 177, 183, 188, 194, 200, 206, 213, 219, 226, 233, 240, 247, 255, 263, 271, 279, 288, 297, 306, 316, 325, 335, 346, 356, 367, 379, 390, 402, 415, 428, 441, 454, 468, 483, 498, 513, 529, 545, 562, 580, 597, 616, 635, 654, 675, 696, 717, 739, 762, 785, 810) y_values <- c(629.6425092, 693.9067558, 754.4664563, 767.5637544, 808.2602174, 794.0798188, 827.8263105, 829.0713063, 942.1401253, 941.4504438, 977.2613896, 988.3319533, 1065.3184551, 1153.8098881, 1141.3217309, 1162.6235085, 1170.0284627, 1176.2804890, 1147.8923481, 1195.5306605, 1179.2821602, 1164.1645349, 1113.1920617, 991.4336153, 1016.4254102, 954.4010424, 942.3961786, 1131.3566435, 1053.4404436, 872.8857897, 741.2625489, 669.3430698, 605.0944916, 593.7124494, 580.5191216, 565.4610143, 549.2083824, 478.9347173, 509.6879804, 328.7164120, 332.8948846, 284.6312054, 280.7722786, 335.8359343, 243.1869010, 268.7471464, 230.1890039, 200.0794310, 222.2806710, 164.0873158, 131.3721738, 112.6710788, 100.8907618, 95.8925401, 77.1103902, 67.2195979, 60.7203287, 54.2668605, 45.4695630, 40.1307280, 35.3640275, 33.1294568, 30.3855069, 25.3479543, 22.4857722, 20.4963634, 19.1942742, 16.0412082, 11.7917180, 11.3206729, 8.9647115, 8.8772804, 7.9883784, 6.5044297, 5.7742390, 4.9888767, 4.3245790, 3.8242901, 3.2763016, 2.8762140, 2.5361281, 2.2526347, 1.9660910, 1.6893935, 1.5069924, 1.3296613, 1.1608268, 1.0178425, 0.9470220, 0.8378081, 0.6925257, 0.6426677, 0.5678900, 0.5064849, 0.4364656, 0.3848985, 0.3521381, 0.3600632, 0.1613892, 0.0000000) Opt <- data.frame(Diam = x_values, dN = y_values) # 定义对数正态拟合模型(含缩放因子A,适配原始数据幅度) log_normal_model <- function(x, A, mu, sigma) { (A / (x * sigma * sqrt(2 * pi))) * exp(-(log(x) - mu)^2 / (2 * sigma^2)) } # 估计初始参数:mu取峰值对应x的对数,sigma取log(x)的标准差,A取y最大值*1000(适配幅度) peak_x <- Opt$Diam[which.max(Opt$dN)] init_params <- list( A = max(Opt$dN) * 1000, mu = log(peak_x), sigma = sd(log(Opt$Diam)) ) # 用nls拟合模型 fit <- nls(dN ~ log_normal_model(Diam, A, mu, sigma), data = Opt, start = init_params) # 生成拟合曲线的x序列(覆盖10到1000,步长1) fit_x <- seq(10, 1000, by = 1) fit_y <- predict(fit, newdata = list(Diam = fit_x)) # 绘制图表:对数X轴,x范围10-1000 plot(Opt$Diam, Opt$dN, log = "x", xlim = c(10, 1000), xlab = "Diameter", ylab = "dN", main = "Log-Normal Fit", pch = 16, col = "black") lines(fit_x, fit_y, col = "blue", lwd = 2) # 输出拟合得到的模型方程参数 cat("拟合得到的对数正态模型参数:\n") print(coef(fit))
关键说明
对数正态模型定义:
不同于你之前尝试的高斯模型(直接对x拟合),对数正态模型针对log(x)做正态分布拟合,公式为:
[
dN = \frac{A}{x \cdot \sigma \cdot \sqrt{2\pi}} \cdot e{-\frac{(\log(x)-\mu)2}{2\sigma^2}}
]
其中A是缩放因子,用于匹配原始数据的幅度(因为原始y值不是概率密度,而是计数类数值)。初始参数设置:
mu:取峰值对应的x值的对数,确保拟合起点靠近数据中心sigma:取原始x值对数的标准差,给出初始的离散程度估计A:用y值最大值乘以系数(这里是1000),保证拟合曲线的幅度和原始数据匹配
绘图设置:
log="x"开启X轴对数刻度,这是让曲线呈现对称形态的关键(对应目标蓝色曲线的样式)xlim=c(10,1000)强制X轴从10开始,覆盖你需要的范围
模型输出:
运行代码后会打印拟合得到的A、mu、sigma参数,你可以将这些参数代入上述公式,得到简洁的拟合方程。
常见问题解决
- 如果nls拟合报错,可尝试用
nlsLM()(来自minpack.lm包),它的鲁棒性更强:install.packages("minpack.lm") library(minpack.lm) fit <- nlsLM(dN ~ log_normal_model(Diam, A, mu, sigma), data = Opt, start = init_params)
内容的提问来源于stack exchange,提问作者DUMB DUMB DEEB
相关产品推荐
相关产品推荐

