R语言nlme、nlmer、lme4用(非)线性混合模型non-linear mixed model分析藻类数据实例

原文连接:http://tecdat.cn/?p=23426 

序言

混合线性模型,又名多层线性模型(Hierarchical linear model)。它比较适合处理嵌套设计(nested)的实验和调查研究数据。此外,它还特别适合处理带有被试内变量的实验和调查数据,由于该模型不须要假设样本之间测量独立,且经过设置斜率和截距为随机变量,能够分离自变量在不一样情境中(被试内设计中常为不一样被试)对因变量的做用。bootstrap

简单的说,混合模型中把研究者感兴趣的自变量对因变量的影响称为固定效应,把其余控制的情景变量称为随机效应。因为模型中包括固定和随机效应,故称为混合线性模型。不管是用方差分析进行差别比较,仍是回归分析研究自变量对因变量的影响趋势,混合线性模型比起传统的线性模型都有更灵活的表现。
 segmentfault

非线性混合模型就是经过一个链接函数将线性模型进行拓展,而且同时再考虑随机效应的模型。app

非线性混合模型经常在生物制药领域的分析中会用到,由于不少剂量反应并非线性的,若是这个时候数据再有嵌套结构,那么就须要考虑非线性混合模型了。dom

 本文中咱们用(非)线性混合模型分析藻类数据。这个问题的参数是:已知截距(0日值)在各组和样本之间是相同的。函数

数据

用lattice和ggplot2绘制数据。测试

xyplot(jitter(X)~Day, groups=Group)

ggplot版本有两个小优点。1. 按个体和群体平均数添加线条[用stat_summary应该和用xyplot的type="a "同样容易]);2.调整点的大小,使重叠的点可视化。(这两点固然能够用自定义的 panel.xyplot 来实现 ...)编码

## 必须用手进行汇总
ggplot(d,aes(x=Day,y=X,colour=Group))

从这些图片中得出的主要结论是:(1)咱们可能应该使用非线性模型,而不是线性模型;(2)可能存在一些异方差(在较低的平均值上有较大的方差,好像在 X=0.7的数据有一个 "天花板");看起来可能存在个体间的变化(特别是基于t2的数据,其中个体曲线近乎平行)。然而,咱们也将尝试线性拟合来讲明问题。url

使用nlme

用lme的线性拟合失败。spa

LME <- lme(X ~ 1, random = ~Day|Individual, data=d)

若是咱们用control=lmeControl(msVerbose=TRUE))运行这个程序,就会获得输出,最后是。 scala

能够看到考虑到组*日效应的模型也失败了。 

LME1 <- lme(X ~ Group*Day, random = ~Day|Individual, data=d)

我试着用SSfpl拟合一个非线性模型,一个自启动的四参数Logistic模型(参数为左渐近线、右渐近线、中点、尺度参数)。这对于nls拟合来讲效果不错,给出了合理的结果。 

nlsfit1 <- nls(X ~ SSfp)
coef(nlsfit1)

能够用gnls来拟合组间差别(我须要指定起始值

个人第一次尝试不太成功。 

gnls(
    X ~ SSfpl)

 但若是我只容许asymp.R在各组之间变化,就能运行成功。 

params=symp.R~Group

绘制预测值。

g1 + geom_line()

这些看起来很不错(若是能获得置信区间就更好了--须要使用delta法或bootstrapping)。 

dp <- data.frame(d,res=resid(gnlsfit2),fitted=fitted(gnlsfit2))
(diagplot1 <- ggplot(dp,aes(x=factor(Individual),
              y=res,colour=Group))+
      geom_boxplot(outlier.colour=NULL)+
  scale\_colour\_brewer(palette="Dark2"))

除了7号样本外,没有不少证据代表个体间的变异......若是咱们想忽略个体间的变异,能够用 

anova(lm(res~Individual))

大的(p\)值能够接受个体间不存在变异的无效假设...

更通常的诊断图--残差与拟合,同一个体的点用线链接。能够发现,随着平均数的增长,方差会逐渐减少。

plot(dp,(x=fitted,y=res,colour=Group))

我不能用nlme来处理三个参数因组而异模型,但若是我只容许asymp变化,就能够运行。 

nlme(model=list(fixed=with(c(asymp.R,xmid,scale,asymp.L),...)

右侧渐近线中的方差估计值是非零的。

加入随机效应后,参数根本就没有什么变化。 

最大的比例差别是3.1%(在比例参数中)。 

nlmefit2 <- update(list(asyR+xmd+scal+asp ~1),
  start )

咱们能够经过AIC或似然比检验来比较模型

AICtab(nlmefit1,nlmefit2,weights=TRUE)

anova(nlmefit1,nlmefit2)

能够作一个F测试而不是 LRT(即考虑到有限大小的修正)。
 

pchisq(iff,df=2,lower.tail=FALSE)

 

##分母很是大的F检验。
pf(diff/2,df1=2,df2=1000000,lower.tail=FALSE)

咱们不知道真正相关的df,但上面的总结代表df是40。 

nlmer

我想如今能够为nlmer获得正确的模型规范,但我找不到一个方便的语法来进行固定效应建模(即在这种状况下容许一些参数因组而异)--当我构建了正确的语法,nlmer没法获得答案。

基本的RE模型(没有群体效应)运行良好。

 nlmer(
  X ~ SSfpl(Day, asy, as, x, s) ~
         asy|Indi,)

根据个人理解,人们只须要构建本身的函数来封装固定效应结构;为了与nlmer一块儿使用,该函数还须要计算相对于固定效应参数的梯度。这有点麻烦,但能够经过修改派生函数生成的函数,使之稍微自动化。

  1. 构建虚拟变量:
mm <- model.matrix(~Group,data=d)
grp2 <- mm\[,2\]
  1. 构建一个函数来评估预测值及其梯度;分组结构是硬编码的。
deriv(~A+((B0+B1\*grp2+B2\*grp3-A)/(1+exp((x-xmid)/scale)
  1. 经过插入与传递给函数的参数名称相匹配的行来查看所产生的函数,并将这些参数名称分配给梯度矩阵。
L1 <- grep("^ +\\\.value +<-")
L2 <- grep("^ +attr\\\(\\\.value",)
eval(parse(text))

尝试一下拟合:

nlmer(
  X ~ fpl(Day, asym, as, asymp, asR3, xmi, sca) ~
         as|Indi,
     start =  list(nlpars)),data=d)

失败了(但我认为这是因为nlmer自己形成的,而不是设置有什么根本性的问题)。为了肯定,我应该按照一样的思路生成一个更大的人工数据集,看看我是否能让它工做起来。

如今咱们能够用稳定版(lme4.0)获得一个答案。

结果不理想

fixef(nlmerfit2)

range(predict(nlmerfit2))

我不能肯定,在nlmer中是否有更简单的方法来作固定效果。

AD模型生成器

咱们还可使用AD模型生成器来解决这个问题。它能够处理更复杂的模型,好比拟合更多参数的群体效应。

部分缘由是我对ADMB的熟悉程度较低,这有点费劲,最后我经过按部就班的步骤才成功。

最小的例子

首先尝试没有随机效应、分组变量等。(即等同于上面的nls拟合)。)

##设置数据:调整名称,等等
d0 <- c(list(nobs=nrow(d)),as.list(d0))
##起始值:调整名称,增长数值
names(svec3) <- gsub("\\\.","",names(svec3))  ## 移除点
svec3$asympR <- 0.6 ## 单一值
## 运行 
do_admb("algae0",
        data,
        params,
        run.opts)

结果不错

固定效应模型

如今尝试用固定效应分组,使用上面构建的虚拟变量(也可使用if语句,或者用R[Group[i]]的for循环中的R值向量,或者(最佳选择)为R传递一个模型矩阵...)。咱们必须使用elem_div而不是/来对两个向量进行元素除法。

model1 <- "
参数部分
   向量 pred(1,nobs) // 预测值
   向量Rval(1,nobs) //预测值

过程部分
   pred = as+elem(Rval-asy,1.0+exp(-(Day-xmid)/scal) 
"

试着用模型矩阵来代替它。

model1B <- "
参数部分
   向量 pred(1,nobs) // 预测值
   向量Rval(1,nobs) //预测值

过程部分
   pred = asym+ele(Rv-asy,1.0+exp(-(Da-xmi)/sc)) 。
"

固然,在参数相同的状况下,也能够工做。

随机效应

如今添加随机效应。回归函数并无彻底实现随机效应模型(尽管这应该在即将到来的版本中被修复),因此咱们用公式减去(n/2 log({RSS}/n)),其中RSS是残差平方和。

model2 <- "
参数部分
   向量 pred(1,nobs) // 预测值
   向量Rval(1,nobs) //预测值

过程部分
   pred = asym+elem
   f = 0.5\*no\*log(norm2(X-pr)/n)+norm2(R)。
"

因为ADMB不处理稀疏矩阵,也不惩罚循环,若是将随机效应实现为(i=1; i<=nobs; i++) Rval[i] += Rsigma*Ru[Group[i]],效率会略高,但我是懒人/我喜欢矩阵表示的紧凑性和可扩展性.

如今咱们终于能够测试R之外的参数的固定效应差别了。

model3 <- "
参数部分
   向量 prd(1,nobs) // 预测值
   向量Rl(1,nobs) // 预测值
   向量 scalal(1,nobs)
   向量xmal(1,nobs)
   sdror opr(1,nobs) //输出预测值

程序部分
   Rval = XR\*Rve+Rsma\*(Z*Ru)。
   xmval = Xd*xdvec;....
   f = 0.5\*nobs\*log(norm2(X-pred)/nobs)+norm2(Ru)
"

结果:

summary(admbfit3)

有一个很是大的AIC差别。如上文所示,对nlme拟合的似然比F测试是做为一种练习......

对于该图,最好是按组指定参数从新进行拟合,而不是按基线+对比度进行拟合。

fit3B <- do_admb(,
        data,
        params,
        re,
        run.opts=run.control)
plot2(list(cc),intercept=TRUE)

如今咱们对标准化的问题很困扰,因此(通过一番折腾)咱们能够在不一样的面板上从新画出群体变化的参数。

诊断图

##放弃条件模式/样本-R估计值

diagplot1 %+% dp2

也许这暗示了两个实验组中更大的差别?

拟合与残差

diagplot2 %+% dp2

叠加预测(虚线):

g1 + geom_line

若是能生成平滑的预测曲线(即对中间的日值),那就更好了,但也更繁琐。

结论

  • 从参数估计中得出的主要结论是,第三组降低得更早一些(xmidvec更小),同时降低得更远(Rvec更低)。

似然分析

计算一个( sigma^2_R ) 似然函数的代码并不难,但运行起来有点麻烦:它很慢,并且计算在置信度下限附近的几个点上出现了非正-无限矩阵;我运行了另外一组值,试图充分覆盖这个区域。

lapply(Rsigmavec,fitfun)
## 尝试填补漏洞
lapply(Rsigmavec2,fitfun)

带有插值样条的剖面图和似然比检验分界线。 

在sigma^2_R 上的95%剖面置信区间是{0.0386,0.2169}。

我没有计算过,但转换后的剖面图(在对应于偏离度与最小偏离度的平方根误差的 y )上,因此二次剖面将是一个对称的V)显示,二次近似对这种状况至关糟糕 ...

ggplot(sigma,sqrt(2*(NLL-min(NLL))+
  geom_point()

扩展

  • 更多地讨论分母df问题。参数引导法/MCMC?
  • 咱们能够尝试在xmid和scale参数中加入随机效应。
  • 在组间或做为X的函数的方差(不管是残差仍是个体间的方差)中可能有额外的模式。

 

最受欢迎的看法

1.基于R语言的lmer混合线性回归模型

2.R语言用Rshiny探索lme4广义线性混合模型(GLMM)和线性混合模型(LMM)

3.R语言线性混合效应模型实战案例

4.R语言线性混合效应模型实战案例2

5.R语言线性混合效应模型实战案例

6.线性混合效应模型Linear Mixed-Effects Models的部分折叠Gibbs采样

7.R语言LME4混合效应模型研究教师的受欢迎程度

8.R语言中基于混合数据抽样(MIDAS)回归的HAR-RV模型预测GDP增加

9.使用SAS,Stata,HLM,R,SPSS和Mplus的分层线性模型HLM

相关文章
相关标签/搜索