setwd(getwd())
dataMA <- read.csv("TableS1_R.csv", sep = ";", header = TRUE)
sitedat <- dataMA[!duplicated(dataMA$Site_Number),] # Datatable with 52 rows, one per site
LoEsc <- as.numeric(as.character(recode(dataMA$Level_of_Evidence,"'LoE3a'=3;'LoE3b'=3.3;'LoE4a'=4;'LoE4b'=4.3")))
dataMA$Forest_Composition <- factor(dataMA$Forest_Composition,levels = c("Con","Mix","Dec"))
dataMA_new <- data.frame(dataMA,LoEsc)
Effect sizes are already included in the data file, but for a matter of clarity, we show how they were calculated and demonstrate that they are the same than those included in the data file.
es <- escalc(measure="SMD",m1i=MT,sd1i=ST,n1i=NT,m2i=MC,sd2i=SC,n2i=NC,data=dataMA_new)
table(round(es$yi,digits=2)==es$Effect_Size)
##
## TRUE
## 348
table(round(es$vi,digits=2)==es$Variance_of_Effect_Size)
##
## TRUE
## 348
Standardized mean difference of stream nitrate concentrations plotted against post-harvest time series. Colours reflect the different harvest types. Most long-term studies were clearcut treatments. Only seven studies had records for more than fifteen years after harvest.
Step-wise reduction of predictors based on a Wald F-test
fullmodel <- lme(yi~Forest_Harvest+Forest_Composition+Time_after_harvest+Catchment_Size+Forest_Age+
Mean_Annual_Temperature+Mean_Annual_Precipitation+Altitude+Harvest_Year,
random=~1+Time_after_harvest|Site_Number,
weights=varFixed(~(vi*LoEsc)),
control=list(sigma=1),
correlation=corCAR1(form=~Time_after_harvest|Site_Number),
method="ML",
data=es)
anova(fullmodel)
## numDF denDF F-value p-value
## (Intercept) 1 295 60.95516 <.0001
## Forest_Harvest 4 39 4.92755 0.0026
## Forest_Composition 2 39 8.92327 0.0006
## Time_after_harvest 1 295 17.32069 <.0001
## Catchment_Size 1 39 0.02904 0.8656
## Forest_Age 1 39 0.48636 0.4897
## Mean_Annual_Temperature 1 39 0.00049 0.9825
## Mean_Annual_Precipitation 1 39 0.23223 0.6326
## Altitude 1 39 17.94309 0.0001
## Harvest_Year 1 39 0.06765 0.7962
anova(update(fullmodel,~.-Mean_Annual_Temperature))
## numDF denDF F-value p-value
## (Intercept) 1 295 60.58795 <.0001
## Forest_Harvest 4 40 4.89894 0.0026
## Forest_Composition 2 40 8.92063 0.0006
## Time_after_harvest 1 295 17.43049 <.0001
## Catchment_Size 1 40 0.03092 0.8613
## Forest_Age 1 40 0.46945 0.4972
## Mean_Annual_Precipitation 1 40 0.21636 0.6444
## Altitude 1 40 18.00338 0.0001
## Harvest_Year 1 40 0.05975 0.8081
anova(update(fullmodel,~.-Mean_Annual_Temperature-Harvest_Year))
## numDF denDF F-value p-value
## (Intercept) 1 295 60.51389 <.0001
## Forest_Harvest 4 41 4.89104 0.0026
## Forest_Composition 2 41 8.92092 0.0006
## Time_after_harvest 1 295 17.43002 <.0001
## Catchment_Size 1 41 0.03145 0.8601
## Forest_Age 1 41 0.46621 0.4986
## Mean_Annual_Precipitation 1 41 0.21447 0.6457
## Altitude 1 41 18.02031 0.0001
anova(update(fullmodel,~.-Mean_Annual_Temperature-Harvest_Year-Catchment_Size))
## numDF denDF F-value p-value
## (Intercept) 1 295 61.75428 <.0001
## Forest_Harvest 4 42 4.98649 0.0022
## Forest_Composition 2 42 8.99249 0.0006
## Time_after_harvest 1 295 17.29220 <.0001
## Forest_Age 1 42 0.49495 0.4856
## Mean_Annual_Precipitation 1 42 0.22289 0.6393
## Altitude 1 42 17.51613 0.0001
anova(update(fullmodel,~.-Mean_Annual_Temperature-Harvest_Year-Catchment_Size-Mean_Annual_Precipitation))
## numDF denDF F-value p-value
## (Intercept) 1 295 62.65931 <.0001
## Forest_Harvest 4 43 5.05354 0.0020
## Forest_Composition 2 43 9.04175 0.0005
## Time_after_harvest 1 295 17.32483 <.0001
## Forest_Age 1 43 0.52504 0.4726
## Altitude 1 43 17.60566 0.0001
anova(update(fullmodel,~.-Mean_Annual_Temperature-Harvest_Year-Catchment_Size-Mean_Annual_Precipitation-Forest_Age))
## numDF denDF F-value p-value
## (Intercept) 1 295 55.58098 <.0001
## Forest_Harvest 4 44 4.45334 0.0041
## Forest_Composition 2 44 8.50799 0.0008
## Time_after_harvest 1 295 18.31443 <.0001
## Altitude 1 44 16.85916 0.0002
#Forward selection
emptymodel <- update(fullmodel,~.-.)
stepAIC(emptymodel,~Forest_Harvest+Forest_Composition+Time_after_harvest+Catchment_Size+Forest_Age+
Mean_Annual_Temperature+Mean_Annual_Precipitation+Altitude+Harvest_Year,direction="forward")
## Start: AIC=959.53
## yi ~ 1
##
## Df AIC
## + Time_after_harvest 1 948.77
## + Forest_Composition 2 950.36
## + Forest_Harvest 4 957.50
## + Altitude 1 959.17
## <none> 959.53
## + Mean_Annual_Temperature 1 959.96
## + Mean_Annual_Precipitation 1 960.66
## + Catchment_Size 1 960.87
## + Harvest_Year 1 961.01
## + Forest_Age 1 961.06
##
## Step: AIC=948.77
## yi ~ Time_after_harvest
##
## Df AIC
## + Forest_Composition 2 939.94
## + Altitude 1 946.99
## + Forest_Harvest 4 947.30
## <none> 948.77
## + Mean_Annual_Temperature 1 949.57
## + Catchment_Size 1 950.28
## + Mean_Annual_Precipitation 1 950.39
## + Harvest_Year 1 950.63
## + Forest_Age 1 950.76
##
## Step: AIC=939.94
## yi ~ Time_after_harvest + Forest_Composition
##
## Df AIC
## + Forest_Harvest 4 937.62
## + Altitude 1 937.72
## <none> 939.94
## + Forest_Age 1 941.74
## + Mean_Annual_Precipitation 1 941.75
## + Harvest_Year 1 941.81
## + Mean_Annual_Temperature 1 941.86
## + Catchment_Size 1 941.86
##
## Step: AIC=937.62
## yi ~ Time_after_harvest + Forest_Composition + Forest_Harvest
##
## Df AIC
## + Altitude 1 925.47
## <none> 937.62
## + Harvest_Year 1 938.85
## + Forest_Age 1 938.94
## + Mean_Annual_Precipitation 1 939.53
## + Mean_Annual_Temperature 1 939.60
## + Catchment_Size 1 939.60
##
## Step: AIC=925.47
## yi ~ Time_after_harvest + Forest_Composition + Forest_Harvest +
## Altitude
##
## Df AIC
## <none> 925.47
## + Forest_Age 1 926.11
## + Catchment_Size 1 927.05
## + Mean_Annual_Precipitation 1 927.06
## + Harvest_Year 1 927.31
## + Mean_Annual_Temperature 1 927.33
## Linear mixed-effects model fit by maximum likelihood
## Data: es
## Log-likelihood: -449.7329
## Fixed: yi ~ Time_after_harvest + Forest_Composition + Forest_Harvest + Altitude
## (Intercept) Time_after_harvest
## 0.516107070 -0.106404194
## Forest_CompositionMix Forest_CompositionDec
## -0.777111243 0.721912517
## Forest_Harvestpatchcut-high Forest_Harvestpatchcut-low
## -0.192602990 0.232387374
## Forest_Harvestselective-high Forest_Harvestselective-low
## -1.200503899 -1.679633414
## Altitude
## 0.001878778
##
## Random effects:
## Formula: ~1 + Time_after_harvest | Site_Number
## Structure: General positive-definite, Log-Cholesky parametrization
## StdDev Corr
## (Intercept) 0.64950485 (Intr)
## Time_after_harvest 0.09474031 -0.071
## Residual 1.00000000
##
## Correlation Structure: Continuous AR(1)
## Formula: ~Time_after_harvest | Site_Number
## Parameter estimate(s):
## Phi
## 0.4251468
## Variance function:
## Structure: fixed weights
## Formula: ~(vi * LoEsc)
## Number of Observations: 348
## Number of Groups: 52
#Backward selection
stepAIC(fullmodel)
## Start: AIC=933.48
## yi ~ Forest_Harvest + Forest_Composition + Time_after_harvest +
## Catchment_Size + Forest_Age + Mean_Annual_Temperature + Mean_Annual_Precipitation +
## Altitude + Harvest_Year
##
## Df AIC
## - Mean_Annual_Precipitation 1 931.48
## - Harvest_Year 1 931.55
## - Mean_Annual_Temperature 1 931.56
## - Catchment_Size 1 931.94
## - Forest_Age 1 932.53
## <none> 933.48
## - Forest_Composition 2 942.27
## - Time_after_harvest 1 943.66
## - Forest_Harvest 4 944.80
## - Altitude 1 945.11
##
## Step: AIC=931.48
## yi ~ Forest_Harvest + Forest_Composition + Time_after_harvest +
## Catchment_Size + Forest_Age + Mean_Annual_Temperature + Altitude +
## Harvest_Year
##
## Df AIC
## - Harvest_Year 1 929.57
## - Mean_Annual_Temperature 1 929.57
## - Catchment_Size 1 929.95
## - Forest_Age 1 930.72
## <none> 931.48
## - Forest_Composition 2 940.98
## - Time_after_harvest 1 941.66
## - Forest_Harvest 4 944.23
## - Altitude 1 944.24
##
## Step: AIC=929.57
## yi ~ Forest_Harvest + Forest_Composition + Time_after_harvest +
## Catchment_Size + Forest_Age + Mean_Annual_Temperature + Altitude
##
## Df AIC
## - Mean_Annual_Temperature 1 927.67
## - Catchment_Size 1 928.00
## - Forest_Age 1 928.92
## <none> 929.57
## - Time_after_harvest 1 939.66
## - Forest_Composition 2 940.16
## - Altitude 1 942.91
## - Forest_Harvest 4 943.09
##
## Step: AIC=927.67
## yi ~ Forest_Harvest + Forest_Composition + Time_after_harvest +
## Catchment_Size + Forest_Age + Altitude
##
## Df AIC
## - Catchment_Size 1 926.11
## - Forest_Age 1 927.05
## <none> 927.67
## - Time_after_harvest 1 937.76
## - Forest_Composition 2 939.48
## - Altitude 1 940.92
## - Forest_Harvest 4 941.49
##
## Step: AIC=926.11
## yi ~ Forest_Harvest + Forest_Composition + Time_after_harvest +
## Forest_Age + Altitude
##
## Df AIC
## - Forest_Age 1 925.47
## <none> 926.11
## - Time_after_harvest 1 935.98
## - Forest_Composition 2 937.74
## - Altitude 1 938.94
## - Forest_Harvest 4 939.64
##
## Step: AIC=925.47
## yi ~ Forest_Harvest + Forest_Composition + Time_after_harvest +
## Altitude
##
## Df AIC
## <none> 925.47
## - Forest_Composition 2 935.97
## - Time_after_harvest 1 937.20
## - Altitude 1 937.62
## - Forest_Harvest 4 937.72
## Linear mixed-effects model fit by maximum likelihood
## Data: es
## Log-likelihood: -449.7329
## Fixed: yi ~ Forest_Harvest + Forest_Composition + Time_after_harvest + Altitude
## (Intercept) Forest_Harvestpatchcut-high
## 0.516107070 -0.192602991
## Forest_Harvestpatchcut-low Forest_Harvestselective-high
## 0.232387374 -1.200503900
## Forest_Harvestselective-low Forest_CompositionMix
## -1.679633414 -0.777111243
## Forest_CompositionDec Time_after_harvest
## 0.721912517 -0.106404194
## Altitude
## 0.001878778
##
## Random effects:
## Formula: ~1 + Time_after_harvest | Site_Number
## Structure: General positive-definite, Log-Cholesky parametrization
## StdDev Corr
## (Intercept) 0.64950485 (Intr)
## Time_after_harvest 0.09474031 -0.071
## Residual 1.00000000
##
## Correlation Structure: Continuous AR(1)
## Formula: ~Time_after_harvest | Site_Number
## Parameter estimate(s):
## Phi
## 0.4251468
## Variance function:
## Structure: fixed weights
## Formula: ~(vi * LoEsc)
## Number of Observations: 348
## Number of Groups: 52
Model selection based on AIC forward or backward selection will result in the same model than Wald F-tests
K sets the uppers limit on the degrees of freedom associated with a smooth (s()). K was determined based on help(choose.k). We have set bs=“ts” to use the thin plate regression splines.
#1 Decision based on residual patterns
fgam4 <- gamm(yi ~ Forest_Harvest + s(Time_after_harvest, bs="ts", k=4) + Forest_Composition + Altitude,
random=list(Site_Number=~Time_after_harvest),
weights=varFixed(~vi*LoEsc),
control=list(sigma=1),
correlation=corCAR1(form=~Time_after_harvest|Site_Number), method="ML", data=es)
plot(fgam4$gam,pages=1,residuals=T) #points are the residuals to whom the line is fitted. Less residuals increase uncertainty
gam.check(fgam4$gam) #not ideal (fourth plot with trend)
gam(residuals(fgam4$gam)~s(Time_after_harvest,bs="ts",k=4),data=es)
##
## Family: gaussian
## Link function: identity
##
## Formula:
## residuals(fgam4$gam) ~ s(Time_after_harvest, bs = "ts", k = 4)
##
## Estimated degrees of freedom:
## 2.59 total = 3.59
##
## GCV score: 7.110808
FinalModel <- gamm(yi ~ Forest_Harvest + s(Time_after_harvest, bs="ts", k=20) + Forest_Composition + Altitude,
random=list(Site_Number=~Time_after_harvest),
weights=varFixed(~(vi*LoEsc)),
control=list(sigma=1),
correlation=corCAR1(form=~Time_after_harvest|Site_Number), method="ML", data=es)
plot(FinalModel$gam,pages=1,residuals=T)
abline(h=0,lty=2)
gam.check(FinalModel$gam)
gam(residuals(FinalModel$gam)~s(Time_after_harvest,bs="ts",k=20),data=es)
##
## Family: gaussian
## Link function: identity
##
## Formula:
## residuals(FinalModel$gam) ~ s(Time_after_harvest, bs = "ts",
## k = 20)
##
## Estimated degrees of freedom:
## 6.33 total = 7.33
##
## GCV score: 6.053701
K= 20 is large enough.
What is the influence of the adjusted weighting, that multiplied level of evidence with variance?
Model_Without_LoE <- gamm(yi ~ Forest_Harvest + s(Time_after_harvest, bs="ts", k=20) + Forest_Composition + Altitude,
random=list(Site_Number=~Time_after_harvest),
weights=varFixed(~(vi)),
control=list(sigma=1),
correlation=corCAR1(form=~Time_after_harvest|Site_Number), method="ML", data=es)
anova(Model_Without_LoE$gam)
##
## Family: gaussian
## Link function: identity
##
## Formula:
## yi ~ Forest_Harvest + s(Time_after_harvest, bs = "ts", k = 20) +
## Forest_Composition + Altitude
##
## Parametric Terms:
## df F p-value
## Forest_Harvest 4 6.375 5.99e-05
## Forest_Composition 2 8.317 3e-04
## Altitude 1 19.004 1.75e-05
##
## Approximate significance of smooth terms:
## edf Ref.df F p-value
## s(Time_after_harvest) 15.31 19.00 18.9 <2e-16
AIC(FinalModel$lme,Model_Without_LoE$lme)
## df AIC
## FinalModel$lme 13 888.8914
## Model_Without_LoE$lme 13 1443.3830
cor.test(es$vi,es$LoEsc)
##
## Pearson's product-moment correlation
##
## data: es$vi and es$LoEsc
## t = 3.1155, df = 346, p-value = 0.00199
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
## 0.06111864 0.26570490
## sample estimates:
## cor
## 0.1651882
Model selection as well as model interpretation is the same in model with and without level-of-evidence weighting.
plot(sqrt(es$vi)~residuals(FinalModel$lme,type="normalized"),ylim=c(1,-1.8),pch=16,ylab="Standard error",xlab="Normalized residuals")
rect(par("usr")[1], par("usr")[3], par("usr")[2], par("usr")[4], col ="grey")
lines((seq(1,-3,length.out=50)+1.96),seq(1,-3,length.out=50))
lines((-seq(1,-3,length.out=50)-1.96),seq(1,-3,length.out=50))
polygon(c(rev(-seq(1,-3,length.out=50)-1.96), seq(1,-3,length.out=50)+1.96), c(rev(seq(1,-3,length.out=50)), seq(1,-3,length.out=50)), col = "white", border = NA)
points(sqrt(es$vi)~residuals(FinalModel$lme,type="normalized"),pch=16,cex=0.5) #model without evidence weighting looks very similar.
abline(v=0)
Funnel plot for the additive mixed effects model. The normalized residuals are symmetrically distributed in a funnel plot and suggests no publication bias.
b1 <- sqrt(es$vi)*sqrt(1/(es$vi*LoEsc))
summary(lm(residuals(FinalModel$lme,type="normalized")*sqrt(1/(es$vi*LoEsc))~b1))
##
## Call:
## lm(formula = residuals(FinalModel$lme, type = "normalized") *
## sqrt(1/(es$vi * LoEsc)) ~ b1)
##
## Residuals:
## Min 1Q Median 3Q Max
## -11.504 -1.024 0.044 1.045 9.713
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.3690 2.0279 0.182 0.856
## b1 -0.6207 3.7264 -0.167 0.868
##
## Residual standard error: 2.29 on 346 degrees of freedom
## Multiple R-squared: 8.018e-05, Adjusted R-squared: -0.00281
## F-statistic: 0.02774 on 1 and 346 DF, p-value: 0.8678
Intercept is not significant. There is no evidence for a publication bias.
FinalModel <- gamm(yi ~ Forest_Harvest + s(Time_after_harvest, bs="tp", k=20) +Forest_Composition+Altitude,
random=list(Site_Number=~Time_after_harvest),
weights=varFixed(~(vi*LoEsc)),control=list(sigma=1),correlation=corCAR1(form=~Time_after_harvest|Site_Number),
method="ML",data=es)
anova(FinalModel$gam)
##
## Family: gaussian
## Link function: identity
##
## Formula:
## yi ~ Forest_Harvest + s(Time_after_harvest, bs = "tp", k = 20) +
## Forest_Composition + Altitude
##
## Parametric Terms:
## df F p-value
## Forest_Harvest 4 7.070 1.80e-05
## Forest_Composition 2 8.823 0.000185
## Altitude 1 25.325 7.99e-07
##
## Approximate significance of smooth terms:
## edf Ref.df F p-value
## s(Time_after_harvest) 11.46 11.46 11.07 <2e-16
AIC(FinalModel$lme)
## [1] 884.4257
grid.arrange(plot(FinalModel$lme,type=c("p","smooth")),
plot(FinalModel$lme,sqrt(abs(resid(.)))~fitted(.),
type=c("p","smooth"),ylab=expression(sqrt(abs(resid)))),
plot(FinalModel$lme,resid(.,type="pearson")~Time_after_harvest,
type=c("p","smooth")),
qqnorm(FinalModel$lme))
Calculating explained and unexplained between-site variability, total variability and within-site variability.
The total between-site variability per year after intervention increased over the years more than the unexplained between-site variability. The upper line represents total variability. The lower line is the between-site variability explained by the model. b) Unexplained between-site variability to total unexplained variability (\(T^2_{\textrm{unexplained}} + S^2\)).