Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R中非线性Langmuir等温线的拟合_R_Nonlinear Functions_Nls_Non Linear Regression - Fatal编程技术网

R中非线性Langmuir等温线的拟合

R中非线性Langmuir等温线的拟合,r,nonlinear-functions,nls,non-linear-regression,R,Nonlinear Functions,Nls,Non Linear Regression,我想为R中的以下数据拟合等温线模型。最简单的等温线模型是这里给出的Langmuir模型。下面给出了我的MWE,它抛出了错误。我想知道是否有等温线模型的R包 X <- c(10, 30, 50, 70, 100, 125) Y <- c(155, 250, 270, 330, 320, 323) Data <- data.frame(X, Y) LangIMfm2 <- nls(formula = Y ~ Q*b*X/(1+b*X), data = Data, start

我想为R中的以下数据拟合等温线模型。最简单的等温线模型是这里给出的Langmuir模型。下面给出了我的MWE,它抛出了错误。我想知道是否有等温线模型的R包

X <- c(10, 30, 50, 70, 100, 125)
Y <- c(155, 250, 270, 330, 320, 323)
Data <- data.frame(X, Y)
LangIMfm2 <- nls(formula = Y ~ Q*b*X/(1+b*X),  data = Data, start = list(Q = 1, b = 0.5), algorith = "port")

Error in nls(formula = Y ~ Q * b * X/(1 + b * X), data = Data, start = list(Q = 1,  : 
  Convergence failure: singular convergence (7)

X我不知道有这样的软件包,我个人认为你不需要,因为这个问题可以用基本的R解决

nls
对起始参数很敏感,因此您应该从一个好的起始猜测开始。您可以很容易地计算
Q
,因为它对应于x-->Inf处等温线的渐近极限,因此从
Q=323
开始是合理的(这是样本数据集中
Y
的最后一个值)

接下来,您可以进行
绘图(数据)
并添加一条等温线,该等温线对应于您的起始参数
Q
b
,并调整
b
,以得出合理的猜测

下图显示了数据集(点)和由
生成的Q=323和b=0.5的探针等温线(数据,行(X,323*0.5*X/(1+0.5*X),列为红色)
(红线)。对我来说,这似乎是一个合理的开始猜测,我用
nls
尝试了一下:

LangIMfm2 <- nls(formula = Y ~ Q*b*X/(1+b*X),  data = Data, start = list(Q = 300, b = 1), algorith = "port")
# Nonlinear regression model
#   model: Y ~ Q * b * X/(1 + b * X)
#    data: Data
#        Q        b 
# 366.2778   0.0721 
#  residual sum-of-squares: 920.6
# 
# Algorithm "port", convergence message: relative convergence (4)

话虽如此,我建议使用更有效的策略,通过在倒数坐标中重写等温线方程,基于模型的线性化:

z <- 1/Data
plot(Y~X,z)
abline(lm(Y~X,z))
M <- lm(Y~X,z)

Q <- 1/coef(M)[1]
# 363.2488 

b <- coef(M)[1]/coef(M)[2]
# 0.0741759 


z您可以在nlme软件包中使用R的SSmicmen自启动函数(见Ritz and Streibig,2008,R非线性回归),该函数通过拟合Michaelis-Menten(MM)方程的线性化形式计算初始参数。幸运的是,MM方程具有一种可适用于朗缪尔方程的形式,S=Smax*x/(KL+x)。我发现nlshelper和tidyverse软件包对于建模和将nls命令的结果导出到表格和绘图中非常有用,尤其是在建模样本组时。以下是我为一组吸附数据建模的代码:

library(tidyverse)
library(nlme)
library(nlshelper)

lang.fit问题在于起始值。我们展示了两种方法,以及一种即使使用问题中的起始值也会收敛的替代方法

1)plinear右侧在Q*b中是线性的,因此最好将b吸收到Q中,然后我们有一个参数,该参数以线性形式输入,因此更容易求解。同样,对于plinear算法,线性参数不需要起始值,因此只需指定b的起始值。对于plinear,nls公式的右侧应指定为乘以线性参数的向量。运行nls的结果,给出下面的
fm0
将是名为
b
.lin
的系数,其中Q=.lin/b

我们已经从
fm0
中得到了答案,但是如果我们想要以
b
Q
而不是
b
的形式进行干净的运行,我们可以使用
fm0
返回的系数所隐含的起始值运行问题中的原始公式,如图所示

fm0 <- nls(Y ~ X/(1+b*X), Data, start = list(b = 0.5), alg = "plinear")

st <- with(as.list(coef(fm0)), list(b = b, Q = .lin/b))
fm <- nls(Y ~ Q*b*X/(1+b*X), Data, start = st)
fm
我们可以显示结果。这些点是数据,红线是拟合曲线

plot(Data)
lines(fitted(fm) ~ X, Data, col = "red")
(地块后续)

2)平均值或者,对Q使用平均值的起始值(数据$Y)似乎效果良好

nls(Y ~ Q*b*X/(1+b*X), Data, start = list(b = 0.5, Q = mean(Data$Y)))
给予:

Nonlinear regression model
  model: Y ~ Q * b * X/(1 + b * X)
   data: Data
       b        Q 
  0.0721 366.2779 
 residual sum-of-squares: 920.6

Number of iterations to convergence: 6 
Achieved convergence tolerance: 5.818e-06
$par
[1] 366.27028219   0.07213613

$value
[1] 920.62

$counts
function gradient 
     249       NA 

$convergence
[1] 0

$message
NULL
这个问题已经有了我们使用的合理的
b
起始值,但是如果需要的话,可以将
Y
设置为
Q*b
,这样它们就可以取消,并
X
取平均值(数据$X),然后求解
b
得到
b=1-1/平均值(数据$X)
。虽然未显示使用
b
的该起始值和
平均值(数据$Y)
作为
Q
的起始值也会导致收敛

3)optim如果我们使用
optim
算法收敛,甚至与问题中使用的初始值一致。我们形成残差平方和,并最小化:

rss <- function(p) {
  Q <- p[1]
  b <- p[2]
  with(Data, sum((Y - b*Q*X/(1+b*X))^2))
}
optim(c(1, 0.5), rss)

只需尝试不同的启动参数,例如
start=list(Q=300,b=1)
谢谢@MaratTalipov提供的有用意见。你知道有没有适合等温线模型的R软件包吗?谢谢@Marat的回答。我认为Lanmuir等温线模型的线性版本和非线性版本有很大的不同,特别是在估计的标准误差方面。一些非线性模型可以转换为线性模型。我的理解是,非线性模型的估计与其线性模型形式之间可能存在一对一的关系,但它们相应的标准误差彼此不相关。这个断言是真的吗?通过转换为线性来拟合非线性模型是否存在缺陷?提前感谢你的帮助。
plot(Data)
lines(fitted(fm) ~ X, Data, col = "red")
nls(Y ~ Q*b*X/(1+b*X), Data, start = list(b = 0.5, Q = mean(Data$Y)))
Nonlinear regression model
  model: Y ~ Q * b * X/(1 + b * X)
   data: Data
       b        Q 
  0.0721 366.2779 
 residual sum-of-squares: 920.6

Number of iterations to convergence: 6 
Achieved convergence tolerance: 5.818e-06
rss <- function(p) {
  Q <- p[1]
  b <- p[2]
  with(Data, sum((Y - b*Q*X/(1+b*X))^2))
}
optim(c(1, 0.5), rss)
$par
[1] 366.27028219   0.07213613

$value
[1] 920.62

$counts
function gradient 
     249       NA 

$convergence
[1] 0

$message
NULL