load("JAGS papier 1/model1_p0_sans_transient_max_especes_50000.RData")
I think the most obvious and safest way to tackle this question is to simply look at the estimates of years effects:
rpti <- grep(x=row.names(model1_p0_sans_transient_max_especes_groupe$BUGSoutput$summary), pattern = "random.phi.temps")[1:15]
par(mar=c(6,4,1,1), las=1)
plot(x=2001:2015, model1_p0_sans_transient_max_especes_groupe$BUGSoutput$summary[rpti,1], ylim=c(-0.8,0.8),
ylab="Year effect (latent scale)", xlab = "", xaxt="n")
axis(side = 1, at = 2001:2015, labels = FALSE)
text(x = 2001:2015, y=par()$usr[3]-0.05*(par()$usr[4]-par()$usr[3]),
labels = paste0(2001:2015, "-", 2001:2015+1), srt=45, adj=1, xpd=TRUE)
abline(h=0, lty=2)
segments(x0=2001:2015,y0 = model1_p0_sans_transient_max_especes_groupe$BUGSoutput$summary[rpti,3],
y1 = model1_p0_sans_transient_max_especes_groupe$BUGSoutput$summary[rpti,7])
In addition, absolute years effects (the dashed line indicate the mean absolute deviation) may be used as a visual guide to identify extreme years (but careful with interpretation! Narrow confidence intervals indicate years were the effect may have positive or negative!):
plot(x=2001:2015, y=apply(abs(model1_p0_sans_transient_max_especes_groupe$BUGSoutput$sims.array[1,,rpti]), MARGIN = 2, FUN = mean),
ylab="Absolute year effect (latent scale)", xlab = "", xaxt="n", ylim=c(0,0.55))
ciaye <- apply(abs(model1_p0_sans_transient_max_especes_groupe$BUGSoutput$sims.array[1,,rpti]), MARGIN = 2, FUN = function(x){HPDinterval(as.mcmc(x))})
segments(x0 = 2001:2015, y0=ciaye[1,], y1=ciaye[2,])
axis(side = 1, at = 2001:2015, labels = FALSE)
text(x = 2001:2015, y=par()$usr[3]-0.05*(par()$usr[4]-par()$usr[3]),
labels = paste0(2001:2015, "-", 2001:2015+1), srt=45, adj=1, xpd=TRUE)
abline(h=mean(apply(abs(model1_p0_sans_transient_max_especes_groupe$BUGSoutput$sims.array[1,,rpti]), MARGIN = 2, FUN=mean)), lty=2)
To me, these graphes suggest that it may not be ideal to think in term of years. The last 8 years are similarly bad, while the 7 first are better (especially the two first one). I wonder if it would not make more sense to think in term of two, or three, periods. I recommend not to try and correlate these deviations with climatic variables, the statisitcal associations would not be powerful and any significant result would have a high probability of being spurious and over-estimated.
The models we have fitted are not appropriate to compare variance among species in different years, because the models assume all species-year deviations come from the same distribution. We can nevertheless estimate the variance among species within each year, knowing that differences among years are likely shrunk, and that the comparison is very conservative. Below I plot the variance in year-species random deviations per-years, and the global estimate for the standard deviation in the random effect species-year, all with 95% credibility intervals.
vptsi <- grep(x=row.names(model1_p0_sans_transient_max_especes$BUGSoutput$summary), pattern = "random.phi.temps.species")
i <- 1:15
spvalarr <- sapply(i, FUN = function(x) {
apply(model1_p0_sans_transient_max_especes$BUGSoutput$sims.array[,1, vptsi[(1:16 - 1)*15+x]], 1, sd)
})
plot(x =2001:2015 , y=apply(spvalarr, 2, mean), ylim = c(0,0.35), ylab="Variation among species within years", xaxt="n", xlab = "")
segments(x0 = 2001:2015, y0 = apply(spvalarr, 2, FUN = function(x){HPDinterval(as.mcmc(x))})[1,],
y1=apply(spvalarr, 2, FUN = function(x){HPDinterval(as.mcmc(x))})[2,])
abline(h=model1_p0_sans_transient_max_especes$BUGSoutput$summary["sigma.phi.temps.species",1], lty=1, lwd=3)
abline(h=model1_p0_sans_transient_max_especes$BUGSoutput$summary["sigma.phi.temps.species","2.5%"], lty=2)
abline(h=model1_p0_sans_transient_max_especes$BUGSoutput$summary["sigma.phi.temps.species","97.5%"], lty=2)
axis(side = 1, at = 2001:2015, labels = FALSE)
text(x = 2001:2015, y=par()$usr[3]-0.05*(par()$usr[4]-par()$usr[3]),
labels = paste0(2001:2015, "-", 2001:2015+1), srt=45, adj=1, xpd=TRUE)
No significant variation among year is apparent.
We can calculate the variance explained by fixed effects from model predictions by taking the products of parameter estimates and predictor values and calculating the variance in these products. Here we have two models, one for precipitations, one for temperature, so the variance calculation ignores interactions and correlations between the two variables.
climdim <- as.vector(model1_p0_sans_transient_max_especes_clim_print_prec$BUGSoutput$sims.array[,,"A_prec_1"])
varprec <- 1:length(climdim)
for (i in 1:length(climdim))
{
varprec[i] <- var(as.vector(model1_p0_sans_transient_max_especes_clim_print_prec$BUGSoutput$sims.array[,,"A_prec_1"])[i]*as.vector(PREC)+
as.vector(model1_p0_sans_transient_max_especes_clim_print_prec$BUGSoutput$sims.array[,,"A_prec_2"])[i]*(as.vector(PREC)^2))
}
vartemp <- 1:length(climdim)
for (i in 1:length(climdim))
{
vartemp[i] <- var(as.vector(model1_p0_sans_transient_max_especes_clim_print_temp$BUGSoutput$sims.array[,,"A_temp_1"])[i]*as.vector(TEMP)+
as.vector(model1_p0_sans_transient_max_especes_clim_print_temp$BUGSoutput$sims.array[,,"A_temp_2"])[i]*(as.vector(TEMP)^2))
}
The variance explained by Spring climate is therefore approximated by:
plot(density(varprec + vartemp, from = 0))
The synchrony calculated from the “group” model was:
0.28897850^2/(0.28897850^2+0.17335992^2+0.08678136^2)
## [1] 0.6896221
We can substitute the synchrony variance component by the climate variance component to estimate the synchrony due to climate:
climvarprop <- ((varprec + vartemp)/(0.28897850^2+0.17335992^2+0.08678136^2))
plot(density(climvarprop, from=0))
mean(climvarprop)
## [1] 0.0837739
quantile(climvarprop , probs = c(0.025, 0.975)) #two ways to calculate CI
## 2.5% 97.5%
## 0.01579548 0.20098301
HPDinterval(as.mcmc(climvarprop)) # more accurate, by sticky zero boundary
## lower upper
## var1 0.005330646 0.178448
## attr(,"Probability")
## [1] 0.9498667
So climate explains 8% (between 1 and 18%) of species-by-time variance.
We can express this result as a proportion of synchrony explained:
mean(climvarprop /(0.28897850^2/(0.28897850^2+0.17335992^2+0.08678136^2)))
## [1] 0.121478
HPDinterval(as.mcmc(climvarprop /(0.28897850^2/(0.28897850^2+0.17335992^2+0.08678136^2))))
## lower upper
## var1 0.007729808 0.258762
## attr(,"Probability")
## [1] 0.9498667
Climate explains about 12% of the synchrony (between 1% and 25%).
Some role for the climatic variables is very reassuring to me! The synchrony must come from somewhere after all! Missing synchrony could be related to the interaction precipitation/temperature, to other weather processes (wind, cover, UV), but more likely in my opinion, to extreme short-term events that cannot be captured by our index: cold-snap, big storm, heat-wave, a month of continuous rain,…
I found the model with interaction temperature-precipitation (including quadratic effects and their interactions). This model accounts for correlations and interactions between temperature and precipitations.
climdim <- as.vector(model1_p0_sans_transient_max_especes_clim_print_prec$BUGSoutput$sims.array[,,"A_prec_1"])
varclim <- 1:length(climdim)
for (i in 1:length(climdim))
{
varclim[i] <- var(
as.vector(model1_p0_sans_transient_max_especes_clim_print$BUGSoutput$sims.array[,,"A_prec_1"])[i]*as.vector(PREC)+
as.vector(model1_p0_sans_transient_max_especes_clim_print$BUGSoutput$sims.array[,,"A_prec_2"])[i]*(as.vector(PREC)^2)+
as.vector(model1_p0_sans_transient_max_especes_clim_print$BUGSoutput$sims.array[,,"A_temp_1"])[i]*as.vector(TEMP)+
as.vector(model1_p0_sans_transient_max_especes_clim_print$BUGSoutput$sims.array[,,"A_temp_2"])[i]*(as.vector(TEMP))^2+
as.vector(model1_p0_sans_transient_max_especes_clim_print$BUGSoutput$sims.array[,,"A_int_temp_prec_1"])[i]*as.vector(PREC)*as.vector(TEMP)+
as.vector(model1_p0_sans_transient_max_especes_clim_print$BUGSoutput$sims.array[,,"A_int_temp_prec_2"])[i]*(as.vector(PREC)^2)*(as.vector(TEMP)^2)+
as.vector(model1_p0_sans_transient_max_especes_clim_print$BUGSoutput$sims.array[,,"A_int_temp_prec_3"])[i]*(as.vector(PREC)^2)*as.vector(TEMP)+
as.vector(model1_p0_sans_transient_max_especes_clim_print$BUGSoutput$sims.array[,,"A_int_temp_prec_4"])[i]*as.vector(PREC)*(as.vector(TEMP)^2)
)
}
climvarprop <- ((varclim)/(0.28897850^2+0.17335992^2+0.08678136^2))
plot(density(climvarprop, from=0))
mean(climvarprop)
## [1] 0.1471521
quantile(climvarprop , probs = c(0.025, 0.975)) #two ways to calculate CI
## 2.5% 97.5%
## 0.04355656 0.31509313
HPDinterval(as.mcmc(climvarprop)) # more accurate, by sticky zero boundary
## lower upper
## var1 0.03183134 0.2911329
## attr(,"Probability")
## [1] 0.9498667
Spring climate explains 14.7% of year-variance (95%CI between 3.2% and 29%).
mean(climvarprop /(0.28897850^2/(0.28897850^2+0.17335992^2+0.08678136^2)))
## [1] 0.2133807
HPDinterval(as.mcmc(climvarprop /(0.28897850^2/(0.28897850^2+0.17335992^2+0.08678136^2))))
## lower upper
## var1 0.04615765 0.422163
## attr(,"Probability")
## [1] 0.9498667
That is 21.3% of the synchrony (between 4.6% and 42.2%).
Manon had some models with a group for migratory and non-migratory species. She disregarded them because they had not converged. I think it is not that bad at all, the three chains agreed on the estimate, and although the MCMC mixing was slow, the chains all had reached a stationary distribution. We could re-run the model for longer to have something clean for the paper, but the results would not change, only the confidence intervals would be estimated a bit more accurately:
vptgi <- grep(x=row.names(model1_p0_sans_transient_max_especes_groupe$BUGSoutput$summary), pattern = "sigma.phi.temps.groupe")
traceplot(model1_p0_sans_transient_max_especes_groupe, varname="sigma.phi.temps.groupe", ask=FALSE )
Looking at the summary of all variance components shows migratory and non-migratory species do not differ much:
vci <- grep(x=row.names(model1_p0_sans_transient_max_especes_groupe$BUGSoutput$summary), pattern = "sigma")
model1_p0_sans_transient_max_especes_groupe$BUGSoutput$summary[vci,]
## mean sd 2.5% 25%
## sigma.p.site 0.66658461 0.06760990 0.539069061 0.61973561
## sigma.p.temps 0.16417933 0.09613517 0.013610121 0.09520911
## sigma.phi.site 0.38695220 0.04671093 0.299086696 0.35471907
## sigma.phi.temps 0.28897850 0.08810207 0.146559013 0.22864787
## sigma.phi.temps.groupe 0.08678136 0.05450199 0.008156848 0.04580734
## sigma.phi.temps.species 0.17335992 0.04322499 0.083024088 0.14635044
## 50% 75% 97.5% Rhat n.eff
## sigma.p.site 0.66485613 0.7108106 0.8059978 1.004256 590
## sigma.p.temps 0.15117478 0.2196978 0.3858143 1.009795 4600
## sigma.phi.site 0.38571392 0.4180743 0.4824899 1.001309 4200
## sigma.phi.temps 0.27795168 0.3352887 0.4989709 1.001938 1800
## sigma.phi.temps.groupe 0.07907557 0.1175062 0.2190103 1.059902 80
## sigma.phi.temps.species 0.17349062 0.2018782 0.2554074 1.067408 110
20% of the variation among species can be attached to migratory/non-migratory behaviours, leaving 80% of the variance attached to species:
(0.08678136^2)/(0.17335992^2+0.08678136^2)
## [1] 0.2003744
Or to put it differently, migratory/non-migratory behaviours explain 6% of the species-time variance:
(0.08678136^2)/(0.28897850^2+0.17335992^2+0.08678136^2)
## [1] 0.06219178
While the synchrnoy corrected for migratory/non-migratory behaviours is still 63%:
(0.28897850^2-0.08678136^2)/(0.28897850^2+0.17335992^2+0.08678136^2)
## [1] 0.6274303