#### This script runs part of the analysis presented in Stephenson et al. 'Parasites of Trinidadian guppies: Evidence for sex- and age-specific trait-mediated indirect effects of predators'. This analysis uses a model averaging approach to the data because we found during stepwise deletion of the model terms that there are several equally well supported models. We also have a number of explanatory variables and wanted to be confident in the parameter estimates and relative importance of these. Please see the text of the paper for more details, and references.
dframe1 <- read.csv(file.choose()) # Select "Trini_data.csv"
###### Check the data is being read correctly
summary(dframe1)
##### Make sure variables are read as either numeric or factors - this also gives a description of each of the columns in the datafile
dframe1$W <- as.numeric(dframe1$wgt) # fish weight
dframe1$gyro<-as.numeric(dframe1$gyro) # count of gyrodactylid parasites on that fish
dframe1$year<-as.factor(dframe1$year) # year the fish was sampled
dframe1$presG<-as.factor(dframe1$presG) # presence/absence of gyrodactylid parasites
dframe1$prestrich<-as.factor(dframe1$prestrich) # presence/absence of trichodina
dframe1$presWS<-as.factor(dframe1$presWS) # presence/absence white spot
dframe1$presApio<-as.factor(dframe1$presApio) # presence/absence apiosoma
dframe1$presfung<-as.factor(dframe1$presfung) # presence/absence fungal infection
dframe1$presDig<-as.factor(dframe1$presDig) # presence/absence of digenean metacercariae
dframe1$presCN<-as.factor(dframe1$presCN) # presence/absence of camallanus nematodes
dframe1$richness.no.gyro<-as.numeric(dframe1$richness.no.gyro) # richness score not including gyrodactylid parasites
dframe1$richness.w.gyro<-as.numeric(dframe1$richness.w.gyro) # richness score including gyrodactylid parasites
dframe1$site<-as.factor(dframe1$site) # arbitrary site number within the course of each river - not useful alone but necessary for the next step:
###### Create nested spatial variables
dframe1 <- within(dframe1, {nriver<-factor(drainage:river)
ncourse <- factor(drainage:river:course)
nsite <- factor(drainage:river:course:site) })
###### create a subsetted dataframe with just 2003, 2004, 2008 because of model convergence issues
dfrn89<-subset(dframe1, year %in% c('2003','2004','2006'))# because the sample sizes for 2008 and 2009 are so much smaller than for the other years there are problems with the model convergence.
###### rescale variables to aid model fitting
library("arm")
dfrn89$presG<-rescale(dfrn89$presG, binary.inputs="0/1")
dfrn89$W<-rescale(dfrn89$W)
dfrn89$prestrich<-rescale(dfrn89$prestrich,binary.inputs="0/1")
###### remove any missing values
dfrn89<-na.omit(dfrn89)
####### construct the global model with all the terms about which you have an a priori hypothesis
library(lme4)
### N.B. The new versions of lme4 have become more sensitive to non-convergence, to the point of producing false positives. This is especially likely in large models like those below. Please note that the messages are warnings only, not error messages, and that lme4 developers are aware that the convergence tests are too sensitive.
model1<-glmer(presG~class+W+year+course+course:class+course:W+class:W+prestrich+prestrich:class+(1|drainage/river/course/site), data=dfrn89, family=binomial, na.action=na.fail, control=glmerControl(optimizer="bobyqa")) ### This model elicits warning messages.
######## RANDOM EFFECTS: simplifying the hierarchical spatial term:
#model 2 has 'drainage' removed, so we have to use the 'nriver' (nested river) term. model 3 and 4 have successively simpler random terms.
model2<-glmer(presG~class+W+year+course+course:class+course:W+class:W+prestrich+prestrich:class+(1|nriver/course/site), data=dfrn89, family=binomial, na.action=na.fail, control=glmerControl(optimizer="bobyqa"))
model3<-glmer(presG~class+W+year+course+course:class+course:W+class:W+prestrich+prestrich:class+(1|ncourse/site), data=dfrn89, family=binomial, na.action=na.fail, control=glmerControl(optimizer="bobyqa"))
model4<-glmer(presG~class+W+year+course+course:class+course:W+class:W+prestrich+prestrich:class+(1|nsite), data=dfrn89, family=binomial, na.action=na.fail, control=glmerControl(optimizer="bobyqa"))
AIC(model1, model2, model3, model4) # compare the AIC values for the models that vary in the random term - model4 has the lowest AIC and is therefore the best.
######## R squared for the models - following Nagakawa and Schielzeth (2013) - compares the effects of the different random terms
library("MuMIn")
r.squaredGLMM(model1) # Gives the marginal (fixed effects only), and conditional (random+fixed effects) R2 for the model - i.e. the proportion of the variation in the data explained by the model
r.squaredGLMM(model2)
r.squaredGLMM(model3)
r.squaredGLMM(model4)
########## Likelihood Ratio Tests for the models to compare random terms
anova(model1, model2, test="Chisq") # LRT to compare two models - they only differ in that model1 contains 'drainage' in the spatial term, so the P value refers to the importance of 'drainage' in the model.
anova(model2, model3, test="Chisq") # LRT to compare two models - they only differ in that model2 contains 'river' in the spatial term, so the P value refers to the importance of 'river' in the model.
anova(model3, model4, test="Chisq") # LRT to compare two models - they only differ in that model3 contains 'course' in the spatial term, so the P value refers to the importance of 'course' in the model.
## N.B. because site is the smallest spatial scale we cannot run the model without it without substantially changing the model (i.e. it would no longer have a random term). We assessed the importance of site by calculating the percentage of variance it explained using the model output. As follows:
summary(model1) # focus on the variance portion of the output: 'Random effects'. The exact numbers might differ depending on the version of lme4 used.
100*(4.42/(4.42+1.89+0.55+0.36)) # percentage explained by site
100*(1.89/(4.42+1.89+0.55+0.36)) # percentage explained by course
100*(0.55/(4.42+1.89+0.55+0.36)) # percentage explained by river
100*(0.36/(4.42+1.89+0.55+0.36)) # percentage explained by drainage
### So putting all of this information together for the random effects - site is the only spatial level which explains a significant portion of the variation - model4 is the best
############FIXED EFFECTS: model averaging
####### Standardise the model so all factors have a mean of 0 and a standard deviation of 0.5 so that you can easily compare/average between models ######
library("arm")
stdz.model <- standardize(model4, standardize.y = FALSE)## this could take some time
summary(stdz.model)
######## Use dredge to go through all the models that are encorporated by the global model, and rank them according to AIC so you can pick the best ones #########
library('MuMIn')
model.set <- dredge(stdz.model, rank='AIC') ## this step could take some time
model.set
######## Select the top models, e.g. define top models as having delta AIC < 4
top.models <- get.models(model.set, subset = delta <4) ## this step could take some time
top.models
summary(top.models)
######## Obtain parameter estimates averaged across the top.models set
averaged.model <- model.avg(top.models,revised.var = TRUE,
adjusted = TRUE, rank = "AIC") # recalculates the model weights, for the set of top models
averaged.model
summary(averaged.model)
confint(averaged.model)