0
$\begingroup$

I am trying to find out whether there is a significant effect of Treatment (factor with 3 levels: GR, BC and WF) on the number of moths captured per night in a field experiment. I have 15 Blocks that each contain all three Treatment levels. I sampled four Blocks per night over 65 nights. I have run a generalised linear mixed effects model with a negative binomial error structure and a partially-crossed random effects structure using lme4 in R. I'm pretty sure I have the random effects structure right, I asked a question about it here. I did all my residual diagnostic checks and the model fit seems fine. A likelihood ratio test comparing the full model with the null model (no Treatment effect) suggested that Treatment was highly significant. This was corroborated by a parametric bootstrap test as well as a comparison of the AICcs. I also looked at the confidence intervals of the parameters using confint(Model) and saw that the 95% CIs for the Treatment "WF" did not overlap zero in relation to the baseline Treatment “GR”. However, when I plot my model predictions with 95% confidence intervals, the CIs are strongly overlapping.

Effect of Treatment on moth abundance

I know that overlapping CIs do not always imply statistical non-significance, but the size of the discrepancy concerns me. I.e., the p-values suggest a highly significant effect (p = 1.987e-10) but the CIs of the predicted values overlap the predicted means of each other. I would not be comfortable showing this plot in a paper and claiming the significance of Treatment effect was p < 0.0001, as it just seems implausible from the plot! To get the CIs, I used Ben Bolker’s function I found here and also tried using bootpredictlme4::bootMer with almost identical results.

I far as I can tell, there are four possibilities. (1) the model is specified wrong and the p-values are unreliable, (2) I have used an inappropriate way to determine the significance of the Treatment effect, (3) the model predictions that I've plotted are wrong, or (4) I don't understand the connection between statistical significance and confidence intervals in model predictions. Or possibly all four.

The R code I used is here...

# Starting with data frame "Moths"

# Relevel Treatment so GR comes first
Moths <- within(Moths, Treatment <- relevel(Treatment, ref = "GR"))
levels(Moths$Treatment) # "GR" "BC" "WF"

# Look at data
str(Moths)
#'data.frame':  711 obs. of  4 variables:
#  $ Abundance: int  16 4 29 47 16 0 12 2 3 0 ...
#$ Treatment: Factor w/ 3 levels "GR","BC","WF": 2 2 2 2 2 2 2 2 2 2 ...
#$ Night_re : Factor w/ 65 levels "Y2018_N06","Y2018_N07",..: 3 7 11 15 19 23 27 31 35 39 ...
#$ Block_re : Factor w/ 15 levels "M_1","M_10","M_11",..: 2 2 2 2 2 2 2 2 2 2 ...

head(Moths, 10)
# Abundance   Treatment  Night_re Block_re
#1         16        BC Y2018_N08     M_10
#2          4        BC Y2018_N12     M_10
#3         29        BC Y2018_N16     M_10
#4         47        BC Y2018_N20     M_10
#5         16        BC Y2018_N24     M_10
#6          0        BC Y2018_N28     M_10
#7         12        BC Y2018_N32     M_10
#8          2        BC Y2018_N36     M_10
#9          3        BC Y2019_N03     M_10
#10         0        BC Y2019_N07     M_10

# Model Abundance as function of Treatment with a random intercept for Night 
# and a random intercept for Block
Mod_1 <- glmer.nb(Abundance ~ Treatment + (1|Night_re) + (1|Block_re), data = Moths)

# Have a look at model
summary(Mod_1)
#Generalized linear mixed model fit by maximum likelihood (Laplace Approximation) ['glmerMod']
#Family: Negative Binomial(5.6851)  ( log )
#Formula: Abundance ~ Treatment + (1 | Night_re) + (1 | Block_re)
#Data: Moths
#
#AIC      BIC   logLik deviance df.resid 
#4803.6   4831.0  -2395.8   4791.6      705 #
#
#Scaled residuals: 
#  Min      1Q  Median      3Q     Max 
#-1.9733 -0.6972 -0.1803  0.4955  4.4589 #

#Random effects:
#  Groups   Name        Variance Std.Dev.
#Night_re (Intercept) 1.33753  1.1565  
#Block_re (Intercept) 0.04765  0.2183  
#Number of obs: 711, groups:  Night_re, 65; Block_re, 15

#Fixed effects:
#  Estimate Std. Error z value Pr(>|z|)    
#(Intercept)  2.29096    0.15856  14.449  < 2e-16 ***
#TreatmentBC  0.05655    0.04897   1.155    0.248    
#TreatmentWF  0.30265    0.04858   6.229 4.68e-10 ***

# Check model assumptions
# First, with DHARMa
library(DHARMa)
sim <- simulateResiduals(fittedModel = Mod_1, n = 1000)
plot(sim) # Looks fine

# Check residuals against fitted values and covariates
modfort <- fortify(Mod_1)

# Residual vs fitted
ggplot(data = modfort, aes(x = .fitted, y= .scresid)) +
  geom_point() # Good

# Residuals vs covariate
ggplot(data = modfort, aes(x = Treatment, y= .scresid)) +
  geom_boxplot() +
  geom_point() # Good

# Check for overdispersion (using Ben Bolker's function)
overdisp_fun <- function(model) {
  rdf <- df.residual(model)
  rp <- residuals(model,type="pearson")
  Pearson.chisq <- sum(rp^2)
  prat <- Pearson.chisq/rdf
  pval <- pchisq(Pearson.chisq, df=rdf, lower.tail=FALSE)
  c(chisq=Pearson.chisq,ratio=prat,rdf=rdf,p=pval)
}
overdisp_fun(Mod_1) # = 0.93 Fine

# Testing significance of parameters

# Test whether Treatment is significant with a likelihood ratio test
drop1(Mod_1, test = "Chisq")
# Model:
# Abundance ~ Treatment + (1 | Night_re) + (1 | Block_re)
# Df    AIC    LRT   Pr(Chi)    
# <none>       4803.6                     
# Treatment  2 4844.3 44.679 1.987e-10 ***

# Test with a parametric bootstrap

# Make a null model
Null_mod_1 <- update(Mod_1,~.-Treatment)

# Compare with parametric bootstrapping
pbkrtest::PBmodcomp.merMod(Mod_1, Null_mod_1, nsim = 1000)
#Parametric bootstrap test; time: 1240.38 sec; samples: 1000 extremes: 0;
#large : Abundance ~ Treatment + (1 | Night_re) + (1 | Block_re)
#small : Abundance ~ (1 | Night_re) + (1 | Block_re)
#stat df   p.value    
#LRT    44.679  2 1.987e-10 ***
#PBtest 44.679     0.000999 ***

# Could be smaller than 0.000999 if nsim was larger

# Compare with AICc
AICc(Mod_1, Null_mod_1)
#           df   AICc
#Mod_1       6 4803.768
#Null_mod_1  4 4844.384

# What are the confidence intervals of the parameters?
confint(Mod_1, oldNames = FALSE)
#Computing profile confidence intervals ...
#                            2.5 %    97.5 %
#sd_(Intercept)|Night_re  0.97646643 1.3952734
#sd_(Intercept)|Block_re  0.13976365 0.3636530
#(Intercept)              1.97519988 2.6046183
#TreatmentBC             -0.03940728 0.1525319
#TreatmentWF              0.20746858 0.3979320

# Everything suggests treatment effect is highly significant

# Plot model predictions

# Using Ben Bolker's function for calculating fixed effect CIs for mixed models

easyPredCI <- function(model,newdata=NULL,alpha=0.05) {
  ## baseline prediction, on the linear predictor (logit) scale:
  pred0 <- predict(model,re.form=NA,newdata=newdata)
  ## fixed-effects model matrix for new data
  X <- model.matrix(formula(model,fixed.only=TRUE)[-2],newdata)
  beta <- fixef(model) ## fixed-effects coefficients
  V <- vcov(model)     ## variance-covariance matrix of beta
  pred.se <- sqrt(diag(X %*% V %*% t(X))) ## std errors of predictions
  ## inverse-link function
  linkinv <- family(model)$linkinv
  ## construct 95% Normal CIs on the link scale and
  ##  transform back to the response (probability) scale:
  crit <- -qnorm(alpha/2)
  linkinv(cbind(conf.low=pred0-crit*pred.se,
                conf.high=pred0+crit*pred.se))
}

# First, make a new data frame with the three Treatment levels
New_X <- expand.grid(Treatment = c("GR", "BC", "WF"))

# Get the predicted responses.
New_Y <- predict(Mod_1, newdata = New_X, type = "response", re.form = NA)

# Add together into a single data frame. 
New_df <- data.frame(New_X, New_Y)

# Get the 95% confidence intervals
cpred1.CI <- easyPredCI(model = Mod_1, newdata = New_X)

# Add it to the data frame:
New_df <- data.frame(New_df, cpred1.CI)

# Plot it
ggplot(data = New_df, aes(x = Treatment, y = New_Y)) +
  geom_point(size = 3) +
  geom_errorbar(aes(ymin = conf.low, ymax = conf.high), width = 0.2)

# Not very convincing!  





$\endgroup$
2
  • $\begingroup$ The p-values are for $H_0: \beta=0$ vs $H_a: \beta\ne 0$. $\endgroup$
    – Dave
    Commented Mar 2, 2020 at 15:35
  • 1
    $\begingroup$ I gather that you make unconditional predictions for the plot, i.e. without specifying the level of the random factors. If I remember correctly, this will add the random effect variance to the model prediction variance, yielding potentially very large CIs. This "only" means that each level of you random effect is very different from another level, but the treatment effects are very consistent across all of them (you very low p-value). To test whether my hunch is correct, set re.form to a specific random effect combination: now the CIs should be nice and small. If not: forget what I wrote. $\endgroup$
    – Carsten
    Commented Mar 2, 2020 at 15:40

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.