使用 nls 和 R 中的自定义数据框拟合指数曲线
Fit an exponential curve using nls with a custom data frame in R
我已经解决了很多关于 SO 的问题,但我无法在相关答案中找到解决我的问题的方法。我有一个像这样的 table 存储为 PAO1.data
:
Name P AO
Prog1 0.654 59.702
Prog2 0.149 49.595
Prog3 0.505 50.538
Prog4 0.777 59.954
Prog5 0.237 49.611
Prog6 0.756 50.630
Prog7 0.560 118.014
Prog8 0.015 53.779
Prog9 0.789 68.096
Prog10 0.825 79.558
我尝试使用 nls 来拟合数据的指数曲线。
df = data.frame(PAO1.data)
p = df$P
ao = df$AO
RMSE <- function(fit, act){
sqrt(mean((fit - act)^2))
}
expmodel = nls(formula = p ~ exp(ao), data = df, start = list(ao = 0.01))
fit1 = fitted.values(expmodel)
err1 = RMSE(fit1, p)
plot(ao, p)
lines(ao, predict(expmodel))
print(err1)
当我尝试 运行 它时,我在创建 expmodel
时收到这些警告消息:
Warning messages:
1: In min(x) : no non-missing arguments to min; returning Inf
2: In max(x) : no non-missing arguments to max; returning -Inf
同时,我在lines()
得到这个错误:
Error in xy.coords(x, y) : 'x' and 'y' lengths differ
Calls: lines -> lines.default -> plot.xy -> xy.coords
我在 SO 上读到的另一个问题 'lengths differing' 错误实际上在 x
和 y
中有不同的长度。但是,我的 x
和 y
(此处 ao
和 p
)的值数量完全相同。
请注意,指数曲线不太可能真正适合,但我正在尝试几种不同的模型,我想知道如何正确使用 nls
以便我可以做到与其他型号相同。
一些相关的curve-fitting问题:
This question 表示起始数据是关键。我的 table 中 AO 的最小值是 0.015,我选择了 0.01,这在我看来已经足够接近了。
询问有关 nls 的问题,答案是使用 lm 使用多项式给出的。我特别需要知道将来如何将 nls 用于很多复杂模型,这对我不起作用。
看起来很有希望,但我无法通过查看该问题和答案找到我的代码中的问题 - 我的代码中也有类似的语句。
我该怎么做?
编辑:
以下是Roland在评论中发布的解决方案截图:(实际数据集更大)
将对 nls 的调用更改为 expmodel = nls(formula = p ~ exp(beta * ao), data = df, start = list(beta = 0.01))
使用 lines(sort(ao), predict(expmodel))
对 AO 值进行排序后
df <- read.table(text = "Name P AO
Prog1 0.654 59.702
Prog2 0.149 49.595
Prog3 0.505 50.538
Prog4 0.777 59.954
Prog5 0.237 49.611
Prog6 0.756 50.630
Prog7 0.560 118.014
Prog8 0.015 53.779
Prog9 0.789 68.096
Prog10 0.825 79.558", header = TRUE)
#use correct syntax:
expmodel = nls(formula = P ~ exp(beta * AO), data = df, start = list(beta = 0.01))
plot(P ~ AO, data = df)
#you could use lines after sorting, but this is more convenient:
curve(predict(expmodel, newdata = data.frame(AO = x)), from = 49, to = 120, add = TRUE)
显然这不是适合您的数据的模型。如您所知,指数函数经过 (0,1)。您应该考虑添加截距。
我已经解决了很多关于 SO 的问题,但我无法在相关答案中找到解决我的问题的方法。我有一个像这样的 table 存储为 PAO1.data
:
Name P AO
Prog1 0.654 59.702
Prog2 0.149 49.595
Prog3 0.505 50.538
Prog4 0.777 59.954
Prog5 0.237 49.611
Prog6 0.756 50.630
Prog7 0.560 118.014
Prog8 0.015 53.779
Prog9 0.789 68.096
Prog10 0.825 79.558
我尝试使用 nls 来拟合数据的指数曲线。
df = data.frame(PAO1.data)
p = df$P
ao = df$AO
RMSE <- function(fit, act){
sqrt(mean((fit - act)^2))
}
expmodel = nls(formula = p ~ exp(ao), data = df, start = list(ao = 0.01))
fit1 = fitted.values(expmodel)
err1 = RMSE(fit1, p)
plot(ao, p)
lines(ao, predict(expmodel))
print(err1)
当我尝试 运行 它时,我在创建 expmodel
时收到这些警告消息:
Warning messages:
1: In min(x) : no non-missing arguments to min; returning Inf
2: In max(x) : no non-missing arguments to max; returning -Inf
同时,我在lines()
得到这个错误:
Error in xy.coords(x, y) : 'x' and 'y' lengths differ
Calls: lines -> lines.default -> plot.xy -> xy.coords
我在 SO 上读到的另一个问题 'lengths differing' 错误实际上在 x
和 y
中有不同的长度。但是,我的 x
和 y
(此处 ao
和 p
)的值数量完全相同。
请注意,指数曲线不太可能真正适合,但我正在尝试几种不同的模型,我想知道如何正确使用 nls
以便我可以做到与其他型号相同。
一些相关的curve-fitting问题:
This question 表示起始数据是关键。我的 table 中 AO 的最小值是 0.015,我选择了 0.01,这在我看来已经足够接近了。
我该怎么做?
编辑:
以下是Roland在评论中发布的解决方案截图:(实际数据集更大)
将对 nls 的调用更改为 expmodel = nls(formula = p ~ exp(beta * ao), data = df, start = list(beta = 0.01))
使用 lines(sort(ao), predict(expmodel))
df <- read.table(text = "Name P AO
Prog1 0.654 59.702
Prog2 0.149 49.595
Prog3 0.505 50.538
Prog4 0.777 59.954
Prog5 0.237 49.611
Prog6 0.756 50.630
Prog7 0.560 118.014
Prog8 0.015 53.779
Prog9 0.789 68.096
Prog10 0.825 79.558", header = TRUE)
#use correct syntax:
expmodel = nls(formula = P ~ exp(beta * AO), data = df, start = list(beta = 0.01))
plot(P ~ AO, data = df)
#you could use lines after sorting, but this is more convenient:
curve(predict(expmodel, newdata = data.frame(AO = x)), from = 49, to = 120, add = TRUE)
显然这不是适合您的数据的模型。如您所知,指数函数经过 (0,1)。您应该考虑添加截距。