使用 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' 错误实际上在 xy 中有不同的长度。但是,我的 xy(此处 aop)的值数量完全相同。

请注意,指数曲线不太可能真正适合,但我正在尝试几种不同的模型,我想知道如何正确使用 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)。您应该考虑添加截距。