我正在尝试将广义线性模型拟合到我的数据中。我在两个(不相等的)时间间隔(白天(9小时)和晚上(15小时))从空气中采集花粉,并根据形态特征将花粉鉴定为樱桃,其他被子植物和裸子植物。
当我查看原始数据时,与白天相比,夜间空气中樱桃花粉的量有一些有趣的趋势,而我采样的两个果园中这些趋势相差很大。我想测量时间间隔如何影响我的模型。
我的问题(非详尽列表:p)
1)我不明白为什么Interval项总是给我Pr(> | z |)的值1。 2)我不知道如何解决不相等的时间间隔。
根据响应变量的格式,我尝试使用两种误差分布(泊松和二项式)来尝试这种glm。
这是我的数据的一个子样本:
Orchard <- c("CSO", "CSO", "CSO", "HBA", "HBA", "HBA")
Interval <- c("AM", "AM", "AM", "PM", "PM", "PM")
Interval.Duration <- c(9,9,9,15,15,15)
PollenType <- c("Cherry", "Other angiosperm", "Other gymnosperm")
Count <- c(0,2,11,245,124,5,0,2,19,80,38,0,1,0,3,200,150,1)
TotalCount <- c(13,13,13,374,374,374,21,21,21,118,118,118,4,4,4,351,351,351)
df <- data.frame(Orchard, Interval, Interval.Duration, PollenType, Count, TotalCount)
df
# Poisson error distribution model
mod <- glm(Count ~ PollenType + Interval + offset(log(TotalCount)), data = df, family = poisson)
summary(mod)
Call:
glm(formula = Count ~ PollenType + Interval + offset(log(TotalCount)),
family = poisson, data = df)
Deviance Residuals:
Min 1Q Median 3Q Max
-5.0076 -3.0242 -0.9525 1.3507 8.8612
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -5.158e-01 1.646e-01 -3.134 0.00172 **
PollenTypeOther angiosperm -5.096e-01 7.117e-02 -7.159 8.1e-13 ***
PollenTypeOther gymnosperm -2.602e+00 1.660e-01 -15.677 < 2e-16 ***
IntervalPM -1.532e-14 1.658e-01 0.000 1.00000
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for poisson family taken to be 1)
Null deviance: 742.63 on 17 degrees of freedom
Residual deviance: 240.61 on 14 degrees of freedom
AIC: 313.04
Number of Fisher Scoring iterations: 7
# Binomial error distribution model
mod.bin <- glm(Count/TotalCount ~ PollenType + Interval, data = df, family = binomial)
summary(mod.bin)
Call:
glm(formula = Count/TotalCount ~ PollenType + Interval, family = binomial,
data = df)
Deviance Residuals:
Min 1Q Median 3Q Max
-1.04298 -0.88408 0.03032 0.56505 1.02296
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -5.805e-01 9.912e-01 -0.586 0.558
PollenTypeOther angiosperm -6.754e-01 1.300e+00 -0.519 0.603
PollenTypeOther gymnosperm 2.558e-01 1.187e+00 0.216 0.829
IntervalPM 7.973e-14 1.016e+00 0.000 1.000
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 9.7044 on 17 degrees of freedom
Residual deviance: 9.1325 on 14 degrees of freedom
AIC: 28.299
Number of Fisher Scoring iterations: 4
Interval的输出1告诉我我做错了什么,或者我在glm中没有正确询问我的问题。
我怀疑问题可能与数据集的格式有关,但我真的不知道从哪里开始。
~~编辑~~
感谢@ Eric-Scott提供详细的反馈。我重新设计了虚拟数据以仅反映Cherry计数,并为每个果园制作了子集,因为我认为将来自两个果园的数据包含在同一模型中并不合理。我按照您的建议使用“ Interval.Duration”作为偏移量。
Orchard <- c("HBA", "CSO")
Interval <- c("AM", "AM", "PM","PM")
Interval.Duration <- c(9,15)
Count <- c(13,4,245,0,80,2,98,1,200,1,530,1,196,2,311,1)
TotalCount <- c(38,7,374,21,118,15,144,4,351,10,884,12,338,34,490,15)
df <- data.frame(Orchard, Interval, Interval.Duration, Count, TotalCount)
df
df.H <- subset(df, Orchard == "HBA")
df.C <- subset(df, Orchard == "CSO")
#HBA data
modH <- glm(Count ~ Interval + offset(log(Interval.Duration)), data = df.H, family = quasipoisson)
Call:
glm(formula = Count ~ Interval + offset(log(Interval.Duration)),
family = quasipoisson, data = df.H)
Deviance Residuals:
Min 1Q Median 3Q Max
-13.392 -6.225 -1.096 6.204 12.226
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 2.6088 0.4263 6.120 0.000869 ***
IntervalPM 0.8843 0.5067 1.745 0.131574
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for quasipoisson family taken to be 88.85893)
Null deviance: 892.38 on 7 degrees of freedom
Residual deviance: 594.73 on 6 degrees of freedom
AIC: NA
Number of Fisher Scoring iterations: 5
#CSO data
modC <- glm(Count ~ Interval + offset(log(Interval.Duration)), data = df.C, family = quasipoisson)
Call:
glm(formula = Count ~ Interval + offset(log(Interval.Duration)),
family = quasipoisson, data = df.C)
Deviance Residuals:
Min 1Q Median 3Q Max
-1.22474 -0.36170 0.05231 0.27453 1.05020
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -1.8971 0.2400 -7.904 0.000218 ***
IntervalPM -1.0986 0.4801 -2.289 0.062070 .
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for quasipoisson family taken to be 0.5185185)
Null deviance: 6.9044 on 7 degrees of freedom
Residual deviance: 3.7649 on 6 degrees of freedom
AIC: NA
Number of Fisher Scoring iterations: 5
使用伪数据,我可以分别在“ HBA”和“ CSO”模型中看到过度分散和分散不足(尽管当我在完整数据集上运行模型时,两者都有过度分散)。
首先,我拟合了负二项式分布的模型,因为我知道零膨胀模型将无助于HBA数据集的过度分散(不存在零)。
library(MASS)
mod.NB <- glm.nb(formula = Count ~ Interval + offset(log(Interval.Duration)), data = df)
summary(mod.NB)
Call:
glm.nb(formula = Count ~ Interval + offset(log(Interval.Duration)),
data = df, init.theta = 0.2822584211, link = log)
Deviance Residuals:
Min 1Q Median 3Q Max
-1.9557 -1.4501 -0.8920 0.3307 0.8569
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) 1.9258 0.6667 2.889 0.00387 **
IntervalPM 0.8753 0.9423 0.929 0.35294
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for Negative Binomial(0.2823) family taken to be 1)
Null deviance: 21.300 on 15 degrees of freedom
Residual deviance: 20.463 on 14 degrees of freedom
AIC: 166.75
Number of Fisher Scoring iterations: 1
Theta: 0.2823
Std. Err.: 0.0836
2 x log-likelihood: -160.7510
按照建议对https://rpubs.com/kaz_yos/pscl-2中的系数求幂,我对模型中的系数“求幂”(是一个词吗?)
exp(coef(mod.NB))
(Intercept) IntervalPM
6.860548 2.399691
如果我正确地解释了此输出,则樱桃花粉粒的平均数量为6.86,而到了晚上,樱桃花粉的平均数量为2.40倍。但是从统计学上讲,夜间花粉的增加在统计上并不比白天大。 (注:忍受我,我的大部分困惑来自解释输出。)
我运行了一个零膨胀模型来处理“ CSO”数据集中的零乱,但是我也不知道如何在这里解释结果。
library(pscl)
#HBA data set
modzH <- zeroinfl(formula = Count ~ Interval, data = df.H, dist = "negbin")
HBA数据集中没有任何零,因此会弹出以下错误(因此出现了上面的NegBin glm)。
Error in zeroinfl(formula = Count ~ Interval, data = df.H, dist = "negbin") :
无效的因变量,最小计数不为零
#CSO data
modzC <- zeroinfl(formula = Count ~ Interval, data = df.C, dist = "negbin")
summary(modzC)
Call:
zeroinfl(formula = Count ~ Interval + offset(log(Interval.Duration)), data = df.C,
dist = "negbin")
Pearson residuals:
Min 1Q Median 3Q Max
-0.8660 -0.3333 0.0610 0.2887 1.1666
Count model coefficients (negbin with log link):
Estimate Std. Error z value Pr(>|z|)
(Intercept) -1.8971 0.3333 -5.691 1.26e-08 ***
IntervalPM -1.0986 0.6667 -1.648 0.0994 .
Log(theta) 13.6976 510.5736 0.027 0.9786
Zero-inflation model coefficients (binomial with logit link):
Estimate Std. Error z value Pr(>|z|)
(Intercept) -28.49 198393.43 0 1
IntervalPM 12.25 198394.44 0 1
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Theta = 888750.384
Number of iterations in BFGS optimization: 23
Log-likelihood: -10.13 on 5 Df
再次根据Ferran Paüls Vergés的建议,对模型中的系数取幂。 (这是因为模型输出以对数为单位给出系数吗?)
## Exponentiated coefficients
expCoef <- exp(coef((modzC)))
expCoef
# count_(Intercept) count_IntervalPM zero_(Intercept) zero_IntervalPM
# 1.500015e-01 3.333271e-01 4.234422e-13 2.092359e+05
并且(如果我理解如何应用)花粉中样本中樱桃花粉的基线数是1.500015e-01,而樱桃花粉粒为零的样品的基线几率是4.234422e-13?我真的不确定这句话,这似乎没有道理。
答案 0 :(得分:0)
您的Count变量绝对分散,这意味着泊松GLM可能会给您带来误导的结果。我可以通过几种方式看到过度分散:首先,残余偏差远大于自由度,其次,如果将模型作为准泊松(https://www.theanalysisfactor.com/glm-r-overdispersion-count-regression/)运行,则分散参数为46,这是一个大于1(假定为泊松分布),绘制直方图可得出长尾巴分布。您有很多零,您可能会受益于使用零膨胀模型。零膨胀模型假设您得到的零来自两个来源:检测零和“真实”零。就是说,也许在第一次观察中确实没有任何樱桃花粉,或者也许在那里,而您只是没有发现它。
我认为您在第一个模型上走的正确。偏移量通常用于说明采样工作量的差异。对我来说,最自然的偏移量候选者是interval.length
,但我可以理解为什么您可能会使用TotalCount
。
从箱线图中看,我认为间隔没有主要影响(p = 1)似乎是合理的,但是如果包括间隔和花粉类型之间的相互作用,则这种相互作用是显着的。如果您仅对Cherry花粉感兴趣,并且仅使用其他花粉类型获取偏移量的TotalPollen,则过滤df,使其仅是Cherry,然后从其中删除PollenType
模型,我敢打赌,您会看到间隔的影响。
mod <- glm(Count ~ PollenType + Interval, offset = log(TotalCount), data = df, family = poisson)
car::Anova(mod)
mod2 <- glm(Count ~ PollenType*Interval, offset = log(TotalCount), data = df, family = quasipoisson)
car::Anova(mod2)
但是我要做的第一件事就是尝试解决过度分散问题。
回复编辑
首先,您说要为每个果园分别建立模型,但没有(data = df
)。如果您确实使用data = df
,则可以将果园作为一个因素,这样您会得到一个很大的时间间隔:果园交互作用,这也许对您很有趣? (尝试查看ggplot(df, aes(x = Interval, y = log(Count), color = Orchard)) + geom_boxplot()
)。
如果将它们分开,则总体上将具有较小的功率,但是如果您对果园之间的差异不感兴趣,听起来您这样做是合理的。您还可以使用所有数据,并在glmer模型中将果园视为随机效应,但这又增加了另一层复杂性。
我将通过对两个果园应用相同类型的模型来使事情变得简单。您的一个果园中没有零的事实使我认为在另一个果园中实际上没有两个零来源。也就是说,您拥有的零是“真实的”,表示没有花粉,而不仅仅是检测花粉。那么也许不是零膨胀吗?如果负数二项分布为负数,那么您必须自己判断零个数是否多于预期。另外,正如您所注意到的,众所周知,解释零膨胀模型非常困难。
关于解释负二项式glm的输出,我个人避免过多看待summary()
。您可以使用它来获取系数(或者可以使用coef()
),但是要测试Interval的重要性,请使用car::Anova(mod.NB)
或创建一个空模型(mod.NB.0 <- glm.nb(formula = Count ~ 1 + offset(log(Interval.Duration)), data = df)
)并使用{ {1}}。