library(ggplot2)

saline<- read.table("Supplementary_Data_1.csv", dec = ".", sep = ",", header = T) # available 
services<- read.table("Supplementary_Data_2.csv", dec = ",", sep = ",", header = T, skip =2)
saline<-saline[-1,]

# data description: 
# saline contains information on environmental lake characteristics; some column explanations: Remoteness stands for the
# distance in km to the next larger city, s_v_ratio is the surface to volume ratio, and sal_var provides the mean 
# standardised range of salinity values recorded during the last 50 years. Ephemeral, fish_p (fish presence), endangered_sp
# (endangered species) and endemic_sp (endemic species) are binomial variables with 1 indicating a yes and 0 a no.

# services contains information on ecosystem service provisioning. 1 indicates a service provision. Catchment_Water
# indicates the substantial water abstraction from rivers flowing into the lake, Populated indicate the population of lake
# shores by human settlements, biomass_harvest indicates non fish biomass harvest

#### Step 1 - data preparation ####

# synchronize the two different data-sets, so that rows are matching 
services<-services[match(saline$lake,services$Lake),]

# compute the number of services recorded per lake; column 8 contains information on whether lake shore is populated 
# and was not counted as service
saline$totalservice<-rowSums(services[,c(5:7,9:14)])

# for downstream analyses we used absolute range of salinity rather than mean-standardised range of salinity. 
saline$sal_range<- saline$salinity * saline$salinity_var

# code water type from three binomial variables into one categorical vairable indicatign the origin/ water type of the lake:
saline$water_type<- "soda"; saline$water_type[saline$continentalsaline==1]<-"saline"
saline$water_type[saline$seawater==1]<-"seawater"

# we are missing comprehensive ecosystem service information from lake Turkana - hence we eliminate it from downstream
# analyes
sal.work<- saline[-match(c('Lake Turkana'), saline$lake),]

### Step 2) Drivers of the number of ecosystem services per lake ##############

# (i) check for colinearity in predictors - that is fine, no r coefficient above 0.5
cor(sal.work[is.na(sal.work$salinity_var)==F,match(c("remoteness", "surface", "volume", "salinity", "salinity_var"), 
                                                   colnames(sal.work))])

# some diagnostics
hist(sal.work$totalservice)
median(sal.work$totalservice)

# (ii) then we check whether transformations to reach the requirement of linearity are required for predictors. We test for each
# predictor whether square or log transformation improve the AIC by 0.3 units (defined as threshold where complexity through
# transformation is outweighed by increased goodness of fit)

# this procedure is repeated for each predictor
sal.work.log<-sal.work
sal.work.sqr<-sal.work

sal.work.log$sal_range<-log(sal.work$sal_range)
sal.work.sqr$sal_range<-(sal.work$sal_range)^2

reference.model<-lm(data = sal.work,  totalservice ~ water_type + remoteness + surface + volume + 
                      surface:volume + salinity + salinity_var + protected + sal_range)
trans.log<-lm(data = sal.work.log, totalservice ~ water_type + remoteness + surface + volume + 
                surface:volume + salinity + salinity_var + protected + sal_range)
trans.sqr<-lm(data = sal.work.sqr, totalservice ~ water_type + remoteness + surface + volume + 
                surface:volume + salinity + salinity_var + protected + sal_range)

AIC(reference.model, trans.log, trans.sqr)
#summary(reference.model)

# These are the required transformations that have been identified:
sal.work.mod<-sal.work
sal.work.mod$surface<-log(sal.work$surface)
sal.work.mod$volume<-log(sal.work$volume)
sal.work.mod$salinity<-log(sal.work$salinity)
sal.work.mod$sal_range<-(sal.work$sal_range)^2

rm(sal.work.log, sal.work.sqr, trans.log, trans.sqr, reference.model)

# (iii) standardise predictors to facilitate comparisons of effect sizes:
predictors.std<-which(is.element(colnames(sal.work.mod), c("remoteness", "surface", "volume", "salinity", "salinity_var")))
for(i in predictors.std){sal.work.mod[,i]<-as.numeric(scale(sal.work.mod[,i])) }

# (iv) start model selection process:
working.hypoth<-lm(data = sal.work,  totalservice ~ water_type + remoteness + surface + volume + 
                                      surface:volume + salinity + salinity_var + protected + sal_range)
# we first eliminated salinity_var and sal_range as these predictors did not contribute substantially to model fit and these
# variables had a lower number of available data points (some NAs)

summary(working.hypoth)

# after full model building process was implemented, the model with the lowest AIC values was: 
mod.1<-lm(data = sal.work.mod, totalservice ~  remoteness + surface     )
summary(mod.1)

# model diagnostics: look alright
plot(mod.1)
library(ggpubr)
ggqqplot(residuals(mod.1))

rm(working.hypoth)

# (v) prepare plots
# get data for plotting
res<-residuals(mod.1)
plotdata<-data.frame(residuals = residuals(mod.1))
plotdata$remote_data<- sal.work.mod$remoteness * mod.1$coefficients[2] + mod.1$coefficients[1] + residuals(mod.1)
plotdata$surface_data<- sal.work.mod$surface * mod.1$coefficients[3] + mod.1$coefficients[1] + residuals(mod.1)
plotdata$remoteness<- sal.work$remoteness
plotdata$surface<- sal.work$surface
plotdata$remote_effect<- sal.work.mod$remoteness * mod.1$coefficients[2] + mod.1$coefficients[1]
plotdata$surface_effect<- sal.work.mod$surface * mod.1$coefficients[3] + mod.1$coefficients[1]

new.surface<-data.frame(surface = sal.work.mod$surface, remoteness=mean(sal.work.mod$remoteness))
x<-as.data.frame(predict(mod.1, new.surface, interval = "confidence", level = 0.95))
plotdata$surface.upr<-x$upr; plotdata$surface.lwr<-x$lwr

new.remoteness<-data.frame(remoteness = sal.work.mod$remoteness, surface=mean(sal.work.mod$surface))
x<-as.data.frame(predict(mod.1, new.remoteness, interval = "confidence", level = 0.95))
plotdata$rem.upr<-x$upr; plotdata$rem.lwr<-x$lwr


# implement the plots
library(ggplot2)
ggplot(data = plotdata, aes(ymin=surface.lwr, ymax = surface.upr, y=surface_data, x=log10(surface))) + 
  
  geom_line(aes(y=surface_effect), colour = "darkred")  +
  theme_bw() + geom_ribbon( alpha = 0.4, fill = "darkred") +geom_point(size = 2.5)


ggplot(data = plotdata, aes(y=remote_data, x= (remoteness))) + geom_line(aes(y=remote_effect), colour = "darkred") + 
  theme_bw() + geom_ribbon(aes(ymin=rem.lwr, ymax = rem.upr), alpha = 0.4, fill = "darkred") + geom_point(size = 2.3)

rm(mod.1, new.remoteness, new.surface, plotdata,x, sal.work.mod)

#### Step 3 - evaluating drivers the number of endangered species per lake ####
# (i) import data
endangered<- read.table("Supplementary_data_3.csv", dec = ".", sep = ",", header = T)

# (ii) synchronize the two different data-sets, so that rows are matching 
endangered<-endangered[match(saline$lake,endangered$Lake),]

# (iii) create merged data
sal.work<-saline; sal.work$end_no<-endangered$End.richness

# (iv) some diagnostics
mean(sal.work$end_no)
sd(sal.work$end_no)
median((sal.work$end_no))
hist(sal.work$end_no)

### start model selection process

# (v) check again for required transformations for linearisation as above
sal.work.log<-sal.work
sal.work.sqr<-sal.work

sal.work.log$salinity_var<-log(sal.work$salinity_var)
sal.work.sqr$salinity_var<-(sal.work$salinity_var)^2

reference.model<-glm(data = sal.work, end_no ~ water_type + remoteness + surface + volume + surface:volume + salinity + 
                      salinity_var + protected, family = poisson(link="log"))
trans.log<-glm(data = sal.work.log, end_no ~ water_type + remoteness + surface + volume + surface:volume + salinity + 
                salinity_var + protected, family = poisson(link="log"))
trans.sqr<-glm(data = sal.work.sqr, end_no ~ water_type + remoteness + surface + volume + surface:volume + salinity + 
                salinity_var + protected, family = poisson(link="log"))

AIC(reference.model, trans.log, trans.sqr)
summary(reference.model)

rm(reference.model, trans.log, trans.sqr, sal.work.log, sal.work.sqr)

# (vi) implement required transformations:
sal.work.mod<-sal.work
sal.work.mod$salinity<-log(sal.work$salinity) # required to stabilise models; further, a linear model results in 
# potentially negative prediction values, which we want to avoid. Hence, we implemented the transformation
sal.work.mod$remoteness<-log(sal.work$remoteness)
sal.work.mod$surface<-log(sal.work$surface)
sal.work.mod$volume<-(sal.work$volume)^2
sal.work.mod$salinity_var<-(sal.work$salinity_var)^2

# (vii) standardise predictors to compare predictor effect sizes:
predictors.std<-which(is.element(colnames(sal.work.mod), c("remoteness", "surface", "volume", "salinity", "salinity_var")))
for(i in predictors.std){sal.work.mod[,i]<-scale(sal.work.mod[,i]) }

# start model selection process
library(glmmTMB)

###### A) first trial - normal regression
stand<-lm(data = sal.work.mod, end_no ~ water_type + remoteness + surface + volume + surface:volume + salinity + 
            salinity_var + protected)
plot(stand)
# diagnostics look terrible!! We have to do something about the non-normality of residuals
rm(stand, predictors.std)

###### B) second trial glm model - with poission model, we have over-dispersion and a problem with 0 inflation. 
# This sloves the problem:
working.hypoth<-glmmTMB(data = sal.work.mod, end_no ~ water_type + remoteness + surface + volume + surface:volume + salinity + 
                           salinity_var + protected, family = nbinom2(link="log"), zi = ~0)
working.hypoth1<-glmmTMB(data = sal.work.mod, end_no ~ water_type + remoteness + surface + volume + surface:volume + salinity + 
                           salinity_var + protected, family = nbinom2(link="log"), zi = ~1)
working.hypoth2<-glmmTMB(data = sal.work.mod, end_no ~ water_type + remoteness + surface + volume + surface:volume + salinity + 
                           salinity_var + protected, zi = ~1)
AIC(working.hypoth , working.hypoth1,working.hypoth2)
# seemingly the inclusion of a 0 inflation term does not help substantially

library(DHARMa) # check residuals
simulateResiduals(working.hypoth, plot = T) # okay - that seems to have solved the problems - check a bit further:
summary(working.hypoth) # wow, there are a lot of things not significant anymore...

shapiro.test(residuals(working.hypoth))
hist(residuals(working.hypoth), breaks = 20)
plot(residuals(working.hypoth1)~ predict(working.hypoth1))
plot(residuals(working.hypoth)~ predict(working.hypoth))
# that is much better, but there seems still the problem with the increasing residual variance with the fitted values...

##### C) Try gls regressions
library(lme4); library(nlme)
# next step: check for the reason why the gls does not work for the full model...
working.hypoth3<-gls(end_no ~ water_type + remoteness + surface + volume + surface:volume + salinity + protected + salinity_var,
                     data = sal.work.mod[is.na(sal.work.mod$salinity_var)==F,], 
                     weights=varExp(form=~ as.numeric(salinity_var)),  method = "REML")
plot(working.hypoth3) 
# we have two problems here - first we have all kind of convergence issues and second the residuals do not look good 
# conclusion: -> let's stay with the glm approach

rm(working.hypoth, working.hypoth1, working.hypoth2, working.hypoth3)

# Test for overdispersion - that is a nice way to test for it:
library(AER)
w<-glm(data = sal.work.mod, end_no ~ water_type + remoteness + surface + volume + surface:volume + salinity + 
         salinity_var + protected, family = poisson(link="log"))
dispersiontest(w,trafo=1)

# Overdispersion is a problem, but it seems that it is not possible to get rid of all residual issues at the same time
# hence, we selected the glm model as option that seems to have the least issues. 

##### D) Model selection
mod0<-glmmTMB(data = sal.work.mod, end_no ~ remoteness + salinity +water_type  + surface + volume + surface:volume  + 
                           salinity_var + protected, family = nbinom2(link="log"), zi = ~0)
summary(mod0)

# remove salinity_var - not much of a loss - as we have some missing data, it seems to be a good idea to continue with this option
mod1<-glmmTMB(data = sal.work.mod[which(is.na(sal.work.mod$salinity_var)==F),], end_no ~ remoteness + salinity +water_type  + surface + volume +
                surface:volume  + protected, family = nbinom2(link="log"), zi = ~0)
AIC(mod0, mod1)

# new reference model
mod0<-glmmTMB(data = sal.work.mod, end_no ~ remoteness + salinity +water_type  + surface + volume + surface:volume  + protected, 
              family = nbinom2(link="log"), zi = ~0)
summary(mod0)

# search other simpler models
mod1<-glmmTMB(data = sal.work.mod, end_no ~ salinity , family = nbinom2(link="log"), zi = ~0)

summary(mod1) # according to AIC model selection, the best model. But there are many models with similar good fit.
# however, if BIC is used instead, this is clearly the best model.

# after the model selection process, we still tried whether different transformations of salinity would, which are not
# stable in multi-predictor models, would improve parsimonity in univariate models. We found that square root 
# transformation is better and hence chose that one. 

sal.work.mod2<-sal.work
sal.work.mod2$salinity<-(sal.work$salinity)^0.5
mod.final<-glmmTMB(data = sal.work.mod2, end_no ~ salinity , family = nbinom2(link="log"), zi = ~0)

AIC(mod1, mod.final)

# get change along the range of predictor(want to have that for salinity):
range.std<-function(x){(x-min(x, na.rm = T))/(max(x, na.rm = T)-min(x, na.rm = T))}

mod<- glmmTMB(data = sal.work.mod2, end_no ~ range.std(salinity), 
             family = nbinom2(link="log"), zi = ~0)
summary(mod) #2.6 species less across the range of salinity
summary(sal.work.mod$end_no)

# plot the relationship
prediction<-(predict(mod.final))^2

ggplot(data = sal.work, aes(y= end_no, x=salinity)) + geom_point()+ theme_bw()+
  geom_line(aes(y=prediction), colour = 'darkred', size = 1)


### Step 5: Plot Salinity distribution of lakes providing ecosystem services ##############
services<-services[match(sal.work$lake,services$Lake),]

table(services$Ramsar, services$Nationally_protected) # three were Ramsar but not nationally protected
services$protected<-0; services$protected[which(services$Ramsar==1 | services$Nationally_protected==1)]<-1

e_services<-colnames(services[,c(4:7,9:14,17)])
services$salinity<-sal.work$salinity

sal<-c(); serv<-c()
for(i in e_services){col<-which(colnames(services)==i)
  sal<-c(sal,services$salinity[services[,i]==1])
  serv<-c(serv, rep(i, length(services$salinity[services[,i]==1])))}

plotdat<-data.frame(sal, serv)
plotdat$serv<-factor(plotdat$serv, levels = c('salts_extraction', 'Other_cultural_services',  'Recreation', 'Science','Catchment_Water',
                                              'Lake_water','waste_water_discharge','protected' ,'End_species','biomass_harvest', 'Fishery'))
x<-aggregate(plotdat$sal, by=list(plotdat$serv), function(x) mean(x))
rm(x, sal, serv,e_services)

library(ggplot2); library(ggridges);library(viridis); library(hrbrthemes)

colour_code10<- c( rgb(0,118,174,maxColorValue=255),rgb(255,116,0,maxColorValue=255),rgb(0,161,59,maxColorValue=255),
                   rgb(239,0,0,maxColorValue=255),rgb(157,99,181,maxColorValue=255),rgb(152,82,70,maxColorValue=255),
                   rgb(246,110,185,maxColorValue=255),rgb(127,124,119,maxColorValue=255),rgb(194,190,44,maxColorValue=255),
                   rgb(0,194,205,maxColorValue=255))

colour_code3<- c( rgb(233,152,51,maxColorValue=255),rgb(119,145,89,maxColorValue=255),rgb(72,108,140,maxColorValue=255))
# 400*700
plotdat$num<-as.numeric(plotdat$serv)
ggplot(data = plotdat, aes(x= sal, fill =serv)) + theme_bw() +
  geom_boxplot(color="black", alpha=0.80, width = 0.2,position=position_dodge(0.35))+
  scale_fill_manual(values = c(colour_code3[rev(c(3,3,2,2,2,3,3,1,1,1,3))]))

### Step 6: Evaluate relationships between Salinity and individual ecosystem services ##############

sal.work<- saline[-match(c('Lake Turkana'), saline$lake),]
services<- services[-match(c('Lake Turkana'), services$Lake),]
services$protected<-0; services$protected[which(services$Ramsar==1 | services$Nationally_protected==1)]<-1
services$salinity<-sal.work$salinity

services$salinity.log<-log(sal.work$salinity+1)
services$salinity.sqr<-(sal.work$salinity)^2
services$salinity.uni<-poly(sal.work$salinity,2)[,2]

plot(sal.work$salinity, services$salinity.log)
plot(sal.work$salinity, services$salinity.uni)

colnames(services[,c(4:7,9:15)])
# not significant: Catchment_Water, waste_water_discharge, biomass_harvest, Recreation, Science, Other_cultural_services
mod.1<-glm(data = services, protected ~ salinity, family = "binomial")
mod.2<-glm(data = services, protected ~ salinity.log, family = "binomial")
mod.3<-glm(data = services, protected ~ salinity.sqr, family = "binomial")
mod.4<-glm(data = services, protected ~ salinity.uni, family = "binomial")
AIC(mod.1,mod.2,mod.3,mod.4)
summary(mod.1)

mod.1<-glm(data = services, Lake_water ~ salinity, family = "binomial")
mod.2<-glm(data = services, Lake_water ~ salinity.log, family = "binomial")
mod.3<-glm(data = services, Lake_water ~ salinity.sqr, family = "binomial")
mod.4<-glm(data = services, Lake_water ~ salinity.uni, family = "binomial")
AIC(mod.1,mod.2,mod.3,mod.4)
summary(mod.4)

mod.1<-glm(data = services, Fishery ~ salinity, family = "binomial")
mod.2<-glm(data = services, Fishery ~ salinity.log, family = "binomial")
mod.3<-glm(data = services, Fishery ~ salinity.sqr, family = "binomial")
mod.4<-glm(data = services, Fishery ~ salinity.uni, family = "binomial")
AIC(mod.1,mod.2,mod.3,mod.4)
summary(mod.2)

mod.1<-glm(data = services, End_species ~ salinity, family = "binomial")
mod.2<-glm(data = services, End_species ~ salinity.log, family = "binomial")
mod.3<-glm(data = services, End_species ~ salinity.sqr, family = "binomial")
mod.4<-glm(data = services, End_species ~ salinity.uni, family = "binomial")
AIC(mod.1,mod.2,mod.3,mod.4)
summary(mod.2)

# significant models
mod.lw<-glm(data = services, Lake_water ~ salinity.uni, family = "binomial")
mod.fish<-glm(data = services, Fishery ~ salinity.log, family = "binomial")
mod.extr<-glm(data = services, salts_extraction ~ salinity.log, family = "binomial")
#mod.protected<-glm(data = services, protected ~ salinity, family = "binomial")
mod.end<-glm(data = services, End_species ~ salinity.log, family = "binomial")
summary(mod.lw)

preds<-predict(mod.end, interval = "confidence" , type = "link", se.fit = TRUE)
critval <- 1.96 ## approx 95% CI

services$upr<- exp(preds$fit+critval*preds$se.fit)/ (1+exp(preds$fit+critval*preds$se.fit))
services$lwr<- exp(preds$fit-critval*preds$se.fit)/ (1+exp(preds$fit-critval*preds$se.fit))
services$fit_final<- exp(preds$fit)/(1+exp(preds$fit))

#320 * 230 or 320 * 190
library(ggplot2)
ggplot(data = services, aes(x =salinity, y = End_species ))+  
  geom_ribbon(aes(ymin = lwr, ymax = upr), fill = "darkred", alpha = 0.3)+
  geom_line(aes(y=fit_final), colour = "darkred", size = 0.8) +
  geom_point(alpha = 0.4) + theme_bw()

preds<-predict(mod.fish, interval = "confidence" , type = "link", se.fit = TRUE)
critval <- 1.96 ## approx 95% CI

services$upr<- exp(preds$fit+critval*preds$se.fit)/ (1+exp(preds$fit+critval*preds$se.fit))
services$lwr<- exp(preds$fit-critval*preds$se.fit)/ (1+exp(preds$fit-critval*preds$se.fit))
services$fit_final<- exp(preds$fit)/(1+exp(preds$fit))

ggplot(data = services, aes(x =salinity, y = Fishery ))+  
  geom_ribbon(aes(ymin = lwr, ymax = upr), fill = "darkred", alpha = 0.3)+
  geom_line(aes(y=fit_final), colour = "darkred", size = 0.8) +
  geom_point(alpha = 0.4) + theme_bw()

preds<-predict(mod.extr, interval = "confidence" , type = "link", se.fit = TRUE)
critval <- 1.96 ## approx 95% CI

services$upr<- exp(preds$fit+critval*preds$se.fit)/ (1+exp(preds$fit+critval*preds$se.fit))
services$lwr<- exp(preds$fit-critval*preds$se.fit)/ (1+exp(preds$fit-critval*preds$se.fit))
services$fit_final<- exp(preds$fit)/(1+exp(preds$fit))

ggplot(data = services, aes(x =salinity, y = salts_extraction ))+  
  geom_ribbon(aes(ymin = lwr, ymax = upr), fill = "darkred", alpha = 0.3)+
  geom_line(aes(y=fit_final), colour = "darkred", size = 0.8) +
  geom_point(alpha = 0.4) + theme_bw()

preds<-predict(mod.lw, interval = "confidence" , type = "link", se.fit = TRUE)
critval <- 1.96 ## approx 95% CI

services$upr<- exp(preds$fit+critval*preds$se.fit)/ (1+exp(preds$fit+critval*preds$se.fit))
services$lwr<- exp(preds$fit-critval*preds$se.fit)/ (1+exp(preds$fit-critval*preds$se.fit))
services$fit_final<- exp(preds$fit)/(1+exp(preds$fit))

library(ggplot2)
ggplot(data = services, aes(x =salinity, y = Lake_water ))+  
  geom_ribbon(aes(ymin = lwr, ymax = upr), fill = "darkred", alpha = 0.3)+
  geom_line(aes(y=fit_final), colour = "darkred", size = 0.8) +
  geom_point(alpha = 0.4) + theme_bw()

preds<-predict(mod.end, interval = "confidence" , type = "link", se.fit = TRUE)
critval <- 1.96 ## approx 95% CI

services$upr<- exp(preds$fit+critval*preds$se.fit)/ (1+exp(preds$fit+critval*preds$se.fit))
services$lwr<- exp(preds$fit-critval*preds$se.fit)/ (1+exp(preds$fit-critval*preds$se.fit))
services$fit_final<- exp(preds$fit)/(1+exp(preds$fit))

library(ggplot2)
ggplot(data = services, aes(x =salinity, y = End_species ))+  
  geom_ribbon(aes(ymin = lwr, ymax = upr), fill = "darkred", alpha = 0.3)+
  geom_line(aes(y=fit_final), colour = "darkred", size = 0.8) +
  geom_point(alpha = 0.4) + theme_bw()
