from Modeling Logistic Growth Data in R | marine global change ecology
收集了狗的生长数据并模拟。
library(car)
library(tidyverse)
# Here's the data
mass <- c(6.25, 10, 20, 23, 26, 27.6, 29.8, 31.6, 37.2, 41.2,
48.7, 54, 54, 63, 66, 72, 72.2, 76, 75) #Wilson's mass in pounds
days.since.birth <- c(31, 62, 93, 99, 107, 113, 121, 127, 148,
161, 180, 214, 221, 307, 452, 482, 923, 955, 1308) #days since Wilson's birth
data <- data.frame(mass, days.since.birth) #create the data frame
plot(mass ~ days.since.birth, data = data) #always look at your data first!```
威尔逊的增长看起来像一个logistic function。
使用nls
函数可以在R中实现logistic增长模型。 “nls”代表非线性最小二乘。
logistic增长函数可以写成:
$$y=phi1/(1+exp(-(phi2+phi3*x)))$$
- y =质量,或者可以是一个群体,或任何表现物流增长的反应变量
- phi1 =第一个参数并且是渐近线(例如稳定质量)
- phi2 =第二个参数,没有什么可说的
- phi3 =第三个参数,也被称为增长参数,描述y接近渐近线的速度
- x =输入变量,时间
y <-phi1/(1+exp(-(phi2+phi3*x)))
“nls”和其他模型(例如普通最小二乘)之间的一个重要区别是“nls”需要初始启动参数。这是因为R会迭代评估和调整模型参数以最小化模型误差(因此最小二乘部分),但R需要一个地方开始。 R中有一些函数避免了输入初始参数的需要,这些函数被称为“自启动”函数,在我们的例子中它将是“SSlogis”函数。但现在,我们将跳过该步骤,并手动给R一些初始参数。
coef(lm(logit(mass/100)~days.since.birth,data=data))
这需要使用logit变换(可能性的对数)的线性模型的系数(斜率和截距),并通过渐近线的合理的第一近似(例如100磅)来缩放y
# (Intercept) days.since.birth
# -1.096091866 0.002362622
然后,我们可以将这些值插入到nls函数中作为启动参数。
wilson<-nls(mass~phi1/(1+exp(-(phi2+phi3*days.since.birth))),
start=list(phi1=100,phi2=-1.096,phi3=.002),data=data,trace=TRUE)
在这里,我们使用起始参数构建模型。 跟踪返回迭代。
# 3825.744 : 100.000 -1.096 0.002
# 3716.262 : 81.463877204 -0.886292540 0.002512256
# 3489.696 : 66.115027751 -0.731862991 0.003791928
# 1927.422 : 63.447368011 -1.036245947 0.007113719
# 204.0813 : 71.10755282 -2.06528377 0.01379199
# 123.3499 : 71.76966631 -2.39321544 0.01639836
# 121.3052 : 71.62701380 -2.45163194 0.01692932
# 121.2515 : 71.58084567 -2.46029145 0.01701556
# 121.2502 : 71.57256235 -2.46167633 0.01702943
# 121.2501 : 71.57121657 -2.46189524 0.01703163
# 121.2501 : 71.57100257 -2.46192995 0.01703198
# 121.2501 : 71.57096862 -2.46193546 0.01703204
第一列是error(平方误差的总和?),其余列是模型参数。 R花了11次迭代来达到它满意的模型参数。
summary(wilson)
#
# Formula: mass ~ phi1/(1 + exp(-(phi2 + phi3 * days.since.birth)))
#
# Parameters:
# Estimate Std. Error t value Pr(>|t|)
# phi1 71.570969 1.201983 59.54 < 2e-16 ***
# phi2 -2.461935 0.162985 -15.11 6.88e-11 ***
# phi3 0.017032 0.001227 13.88 2.42e-10 ***
# ---
# Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#
# Residual standard error: 2.753 on 16 degrees of freedom
#
# Number of iterations to convergence: 11
# Achieved convergence tolerance: 1.985e-06
我们可以看到,我们的初始参数并不太遥远。
接下来,我们来创建模型预测并绘制数据。 (我注意到复制和粘贴这个ggplot脚本在R中不起作用,因为有引号,任何人都知道这个解决方案吗?暂时,只需用R或R Studio中的常规引号替换本文中的引号即可。
#set parameters
phi1<-coef(wilson)[1]
phi2<-coef(wilson)[2]
phi3<-coef(wilson)[3]
x<-c(min(data$days.since.birth):max(data$days.since.birth)) #construct a range of x values bounded by the data
y<-phi1/(1+exp(-(phi2+phi3*x))) #predicted mass
predict<-data.frame(x,y) #create the prediction data frame#And add a nice plot (I cheated and added the awesome inset jpg in another program)
ggplot(data=data,aes(x=days.since.birth,y=mass))+
geom_point(color='blue',size=5)+theme_bw()+
labs(x='Days Since Birth',y='Mass (lbs)')+
scale_x_continuous(breaks=c(0,250,500,750, 1000,1250))+
scale_y_continuous(breaks=c(0,10,20,30,40,50,60,70,80))+
theme(axis.text=element_text(size=18),axis.title=element_text(size=24))+
geom_line(data=predict,aes(x=x,y=y), size=1)