R 中的零膨胀过度分散计数数据 glmmTMB 错误

zero-inflated overdispersed count data glmmTMB error in R

我正在处理计数数据(可用 here) that are zero-inflated and overdispersed and has random effects. The package best suited to work with this sort of data is the glmmTMB (details here and troubleshooting here)。

在处理数据之前,我检查了它的正态性(零膨胀)、方差同质性、相关性和异常值。数据有两个异常值,我从上面的数据集 linekd 中删除了它们。有来自 18 个位置 (prop_id) 的 351 个观测值。

数据如下所示:

euc0 ea_grass ep_grass np_grass np_other_grass month year precip season   prop_id quad
 3      5.7      0.0     16.7            4.0     7 2006    526 Winter    Barlow    1
 0      6.7      0.0     28.3            0.0     7 2006    525 Winter    Barlow    2
 0      2.3      0.0      3.3            0.0     7 2006    524 Winter    Barlow    3
 0      1.7      0.0     13.3            0.0     7 2006    845 Winter    Blaber    4
 0      5.7      0.0     45.0            0.0     7 2006    817 Winter    Blaber    5
 0     11.7      1.7     46.7            0.0     7 2006    607 Winter    DClark    3

响应变量为 euc0,随机效应为 prop_idquad_id。其余变量是固定效应(均代表不同植物物种的覆盖百分比)。

我要的型号运行:

library(glmmTMB)
seed0<-glmmTMB(euc0 ~ ea_grass + ep_grass + np_grass + np_other_grass + month + year*precip + season*precip + (1|prop_id)  + (1|quad), data = euc, family=poisson(link=identity))

fit_zinbinom <- update(seed0,family=nbinom2) #allow variance increases quadratically

我在 运行 宁 seed0 代码后得到的错误是:

Error in optimHess(par.fixed, obj$fn, obj$gr) : gradient in optim evaluated to length 1 not 15 In addition: There were 50 or more warnings (use warnings() to see the first 50)

warnings() 给出:

1. In (function (start, objective, gradient = NULL, hessian = NULL,  ... :
  NA/NaN function evaluation

我通常也指居中和标准化我的数值变量,但这只会消除第一个错误并保留 NA/NaN 错误。我尝试添加 glmmTMBControl 语句,如 ,但它打开了一个全新的错误世界。

我该如何解决这个问题?我做错了什么?

如有详细说明,我将不胜感激,以便我以后可以更好地学习如何解决此问题。 或者,我对 MCMCglmm 解决方案持开放态度,因为该函数也可以处理此类数据(尽管 运行 需要更长的时间)。

答案不完整...

  • identity-link 有限域响应分布模型(例如 Gamma 或 Poisson,其中不可能出现负值)在计算上存在问题;在我看来,它们在概念上也经常存在问题,尽管有一些合理的论据支持它们。你有充分的理由这样做吗?
  • 对于您要拟合的模型,这是一个非常小的数据集:13 个固定效应预测变量和 2 个随机效应预测变量。经验法则是您需要大约 10-20 倍的观测值:似乎 适合您的 345 次左右的观测值,但是......只有 40 次观测值是非零的!这意味着您的 'effective' 数量的 observations/amount 信息将少得多(有关这一点的更多讨论,请参阅 Frank Harrell 的 回归建模策略 )。

话虽如此,让我 运行 回顾一下我尝试过的一些事情以及最终的结果。

  • GGally::ggpairs(euc, columns=2:10) 没有检测到任何明显糟糕的数据(我确实用 euc0==78 丢弃了数据点)

为了尝试使 identity-link 模型工作,我在 glmmTMB 中添加了一些代码。您应该能够通过 remotes::install_github("glmmTMB/glmmTMB/glmmTMB@clamp") 安装(请注意,您需要安装编译器等才能安装它)。此版本采用负预测值并强制它们为非负,同时对负对数似然添加相应的惩罚。

使用新版本的 glmmTMB 我没有收到错误,但我确实收到了这些警告:

Warning messages: 1: In fitTMB(TMBStruc) : Model convergence problem; non-positive-definite Hessian matrix. See vignette('troubleshooting')
2: In fitTMB(TMBStruc) : Model convergence problem; false convergence (8). See vignette('troubleshooting')

Hessian(二阶导数)矩阵是非正定的意味着存在一些(仍然难以解决)问题。 heatmap(vcov(f2)$cond,Rowv=NA,Colv=NA) 让我看看协方差矩阵。 (我也喜欢 corrplot::corrplot.mixed(cov2cor(vcov(f2)$cond),"ellipse","number"),但当 vcov(.)$cond 是非正定时,这不起作用。在紧要关头,你可以使用 sfsmisc::posdefify() 强制它是正定的......)

尝试缩放:

eucsc <- dplyr::mutate_at(euc1,dplyr::vars(c(ea_grass:precip)), ~c(scale(.)))

这会有所帮助 - 现在我们仍在做一些愚蠢的事情,例如将年份视为数字变量而不将其居中(因此模型的 'intercept' 是公历的第 0 年...)

但这仍然不能解决问题。

更仔细地观察 ggpairs 图,看起来 seasonyear 混淆了:with(eucsc,table(season,year)) 表明观察发生在 Spring 和一年是冬天,另一年是秋天。 seasonmonth 也很困惑:如果我们知道月份,那么我们就自动知道季节。

此时我决定放弃身份 link 看看会发生什么。 update(<previous_model>, family=poisson)(即使用泊松和标准对数 link)有效!使用 family=nbinom2 也是如此。

我查看了结果,发现降水 X 季节系数的 CI 很疯狂,因此删除了交互项 (update(f2S_noyr_logNB, . ~ . - precip:season)),此时结果看起来很合理。

一些最后的说明:

  • 与样方相关的方差实际上为零
  • 我认为你不一定需要零-inflation;低均值和过度分散(即 family=nbinom2)可能就足够了。
  • 残差分布看起来不错,但似乎仍然存在一些模型失配 (library(DHARMa); plot(simulateResiduals(f2S_noyr_logNB2)))。我会花一些时间针对各种预测变量组合绘制残差和预测值,看看您是否可以定位问题。

PS 一种快速查看固定效应(多重共线性)问题的方法:

X <- model.matrix(~ ea_grass + ep_grass +
                   np_grass + np_other_grass + month +
                   year*precip + season*precip,
                  data=euc)
ncol(X)  ## 13
Matrix::rankMatrix(X) ## 11

lme4 有这样的测试,以及自动删除别名列的机制,但它们目前没有在 glmmTMB 中实现。