meta analysis

PRISMA GUIDELINES

SYNTHESIS METHODS (statistical synthesis methods) 13d Item:

Describe any methods used to synthesise results and provide a rationale for the choice(s). If meta-analysis was performed, describe the model(s), method(s) to identify the presence and extent of statistical heterogeneity, and software package(s) used. Elements: • If statistical synthesis methods were used, reference the software, packages and version numbers used to implement synthesis methods. • If it was not possible to conduct a meta-analysis, describe and justify the synthesis methods or summary approach used.

If meta-analysis was done, specify:

  • the meta-analysis model (fixed-effect, fixed-effects or random-effects) and provide rationale for the selected model.

  • the method used (e.g. Mantel-Haenszel, inverse-variance).

  • any methods used to identify or quantify statistical heterogeneity (e.g. visual inspection of results, a formal statistical test for heterogeneity, heterogeneity variance (𝜏 2 ), inconsistency (e.g. I2 ), and prediction intervals).

If a random-effects meta-analysis model was used:

  • specify the between-study (heterogeneity) variance estimator used (e.g. DerSimonian and Laird, restricted maximum likelihood (REML)).

  • specify the method used to calculate the confidence interval for the summary effect (e.g. Wald-type confidence interval, Hartung-Knapp-SidikJonkman).

  • consider specifying other details about the methods used, such as the method for calculating confidence limits for the heterogeneity variance. •

If a Bayesian approach to meta-analysis was used, describe the prior distributions about quantities of interest (e.g. intervention effect being analysed, amount of heterogeneity in results across studies).

• If multiple effect estimates from a study were included in a meta-analysis, describe the method(s) used to model or account for the statistical dependency (e.g. multivariate meta-analysis, multilevel models or robust variance estimation).

• If a planned synthesis was not considered possible or appropriate, report this and the reason for that decision.

SYNTHESIS METHODS (methods to explore heterogeneity) 13e Item:

Describe any methods used to explore possible causes of heterogeneity among study results (e.g. subgroup analysis, meta-regression). Elements: • If methods were used to explore possible causes of statistical heterogeneity, specify the method used (e.g. subgroup analysis, meta-regression).

• If subgroup analysis or meta-regression was performed, specify for each:

  • which factors were explored, levels of those factors, and which direction of effect modification was expected and why (where possible).

  • whether analyses were conducted using study-level variables (i.e. where each study is included in one subgroup only), within-study contrasts (i.e. where data on subsets of participants within a study are available, allowing the study to be included in more than one subgroup), or some combination of the above.

  • how subgroup effects were compared (e.g. statistical test for interaction for subgroup analyses).

• If other methods were used to explore heterogeneity because data were not amenable to meta-analysis of effect estimates (e.g. structuring tables to examine variation in results across studies based on subpopulation), describe the methods used, along with the factors and levels.

• If any analyses used to explore heterogeneity were not pre-specified, identify them as such.

SYNTHESIS METHODS (sensitivity analyses) 13f Item:

Describe any sensitivity analyses conducted to assess robustness of the synthesised results. Elements:

• If sensitivity analyses were performed, provide details of each analysis (e.g. removal of studies at high risk of bias, use of an alternative meta-analysis model).

• If any sensitivity analyses were not pre-specified, identify them as such.

**Linear Mixed-Effects Model

#  libraries 
library(readr)
library(dplyr)
library(lme4)
library(lmerTest)     
library(kableExtra)   
library(tibble) 

#  data 
data_mt <- read_csv("Data/mt.csv") %>%
  select(driver, problem, outcome, taxa, auth.year, response.var) %>%
  mutate(
    outcome_num = case_when(
      outcome == "Decrease" ~ -1,
      outcome == "No effect" ~ 0,
      outcome == "Increase" ~ 1,
      TRUE ~ NA_real_
    ),
    across(c(driver, taxa, response.var, auth.year), as.factor)
  ) %>%
  filter(!is.na(outcome_num))

# model
model <- lmer(outcome_num ~ driver + taxa + response.var + (1 | auth.year), data = data_mt)

#  ANOVA 
anova_df <- anova(model) %>%
  as.data.frame() %>%
  mutate(Term = rownames(.)) %>%
  relocate(Term)

#  ANOVA table 
anova_df %>%
  kable("html", caption = "ANOVA Results", digits = 3) %>%
  kable_styling(full_width = FALSE, font_size = 11)
ANOVA Results
Term Sum Sq Mean Sq NumDF DenDF F value Pr(>F)
driver driver 31.666 2.879 11 208.923 6.338 0.000
taxa taxa 1.256 0.251 5 227.369 0.553 0.736
response.var response.var 5.507 0.501 11 222.968 1.102 0.360
#  Fixed effects summary with confidence intervals from the model results
summary_df <- summary(model)$coefficients %>%
  as.data.frame() %>%
  rownames_to_column("Term")

ci_df <- confint(model, method = "Wald") %>%
  as.data.frame() %>%
  rownames_to_column("Term") %>%
  filter(!Term %in% c(".sig01", "sigma")) %>%
  rename(`CI_2.5` = `2.5 %`, `CI_97.5` = `97.5 %`)

# Combine fixed effects with confidence intervals
effects_df <- left_join(summary_df, ci_df, by = "Term")

# --- Display Fixed Effects Table 
effects_df %>%
  select(Term, Estimate, `Std. Error`, `t value`, `Pr(>|t|)`, CI_2.5, CI_97.5) %>%
  kable("html", caption = "Fixed Effects Estimates with 95% Confidence Intervals", digits = 3) %>%
  kable_styling(full_width = FALSE, font_size = 11)
Fixed Effects Estimates with 95% Confidence Intervals
Term Estimate Std. Error t value Pr(>|t|) CI_2.5 CI_97.5
(Intercept) 0.168 0.449 0.373 0.709 -0.713 1.049
driverForest management, removal of invasive species and reforestation 1.099 0.182 6.041 0.000 0.743 1.456
driverFragmentation 0.119 0.217 0.550 0.583 -0.306 0.544
driverGrowth of invasive species 0.393 0.877 0.448 0.654 -1.325 2.111
driverIndustrial disturbance -0.204 0.309 -0.659 0.511 -0.808 0.401
driverLogging and deforestation -0.035 0.203 -0.172 0.864 -0.434 0.364
driverNatural Phenomena 0.820 0.647 1.266 0.207 -0.449 2.089
driverPrescribed fire 0.961 0.305 3.146 0.002 0.362 1.560
driverRegrowth/Regeneration 1.301 0.635 2.049 0.042 0.057 2.546
driverRestoration of a mine 1.388 0.594 2.337 0.020 0.224 2.552
driverUrbanisation and infrastructure development -0.061 0.190 -0.321 0.748 -0.433 0.311
driverWildfire -0.015 0.269 -0.056 0.955 -0.543 0.512
taxaBats -0.397 0.399 -0.997 0.320 -1.179 0.384
taxaBirds -0.441 0.410 -1.075 0.284 -1.244 0.363
taxaInsects -0.108 0.562 -0.192 0.848 -1.210 0.994
taxaMammals -0.657 0.642 -1.024 0.307 -1.915 0.600
taxaSoundscape -0.543 0.413 -1.315 0.190 -1.352 0.266
response.varACI and complexity 0.172 0.377 0.457 0.648 -0.566 0.911
response.varActivity -0.163 0.220 -0.742 0.459 -0.594 0.268
response.varADI, diversity and richness -0.234 0.207 -1.135 0.258 -0.639 0.170
response.varAEI 1.155 0.595 1.941 0.054 -0.011 2.321
response.varBI -0.292 0.349 -0.837 0.403 -0.976 0.392
response.varComposition -0.083 0.323 -0.255 0.799 -0.717 0.552
response.varDistribution 0.102 0.830 0.123 0.902 -1.525 1.729
response.varH 0.025 0.460 0.054 0.957 -0.877 0.927
response.varNDSI 0.225 0.505 0.446 0.656 -0.764 1.214
response.varOccupancy 0.135 0.283 0.475 0.635 -0.421 0.690
response.varSoundscape saturation 0.222 0.422 0.526 0.600 -0.605 1.049
##REFERENCE https://rpubs.com/bbolker/glmmchapter#:~:text=fixef()%20to%20extract%20the%20vector%20of%20fixed%2Deffect,which%20I%20don't%20find%20useful%20very%20often)

###**Bayesian multinomial model

# Load required packages
library(brms)
library(dplyr)
library(ggplot2)
library(ggeffects)
library(readr)

# Step 1: Load and prepare data
df <- read_csv("Data/mt.csv", show_col_types = FALSE) %>%
  filter(outcome %in% c("Increase", "Decrease", "No effect")) %>%
  mutate(
    outcome = factor(outcome, levels = c("No effect", "Decrease", "Increase")), # Baseline = "No effect"
    habitat_change = ifelse(problem == "Habitat gain", "gain", "loss"),
    habitat_change = factor(habitat_change),
    taxa = factor(taxa),
    auth.year = factor(auth.year)
  )

# Step 2: Define priors for multinomial logit model
prior <- c(
  set_prior("normal(0, 2)", class = "Intercept", dpar = "muDecrease"),
  set_prior("normal(0, 2)", class = "Intercept", dpar = "muIncrease"),
  set_prior("normal(0, 1.5)", class = "b", dpar = "muDecrease"),
  set_prior("normal(0, 1.5)", class = "b", dpar = "muIncrease")
)

# Step 3: Fit the model using brms (categorical family)
model <- brm(
  formula = outcome ~ habitat_change * taxa + (1 | auth.year),
  data = df,
  family = categorical(link = "logit"),
  prior = prior,
  chains = 4,
  iter = 4000,
  warmup = 2000,
  control = list(adapt_delta = 0.95),
  file = "bayes_multinomial_habitat_model"  # Saves model
)


# Step 4: Model 
summary(model)
 Family: categorical 
  Links: muDecrease = logit; muIncrease = logit 
Formula: outcome ~ habitat_change * taxa + (1 | auth.year) 
   Data: df (Number of observations: 297) 
  Draws: 4 chains, each with iter = 4000; warmup = 2000; thin = 1;
         total post-warmup draws = 8000

Multilevel Hyperparameters:
~auth.year (Number of levels: 188) 
                         Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS
sd(muDecrease_Intercept)     2.04      0.58     0.97     3.25 1.00     1351
sd(muIncrease_Intercept)     2.09      0.64     0.89     3.46 1.00     1457
                         Tail_ESS
sd(muDecrease_Intercept)     2206
sd(muIncrease_Intercept)     1634

Regression Coefficients:
                                             Estimate Est.Error l-95% CI
muDecrease_Intercept                             0.67      1.02    -1.37
muIncrease_Intercept                             4.17      0.99     2.31
muDecrease_habitat_changeloss                    2.29      1.00     0.35
muDecrease_taxaBats                             -0.66      1.00    -2.65
muDecrease_taxaBirds                             0.61      1.05    -1.46
muDecrease_taxaInsects                           0.11      1.30    -2.44
muDecrease_taxaMammals                           0.91      1.33    -1.67
muDecrease_taxaSoundscape                        0.42      1.07    -1.67
muDecrease_habitat_changeloss:taxaBats           0.54      1.01    -1.44
muDecrease_habitat_changeloss:taxaBirds          0.66      1.11    -1.45
muDecrease_habitat_changeloss:taxaInsects        0.09      1.30    -2.47
muDecrease_habitat_changeloss:taxaMammals        0.32      1.43    -2.39
muDecrease_habitat_changeloss:taxaSoundscape     1.51      1.15    -0.66
muIncrease_habitat_changeloss                   -2.20      0.98    -4.17
muIncrease_taxaBats                             -0.73      0.95    -2.58
muIncrease_taxaBirds                             0.32      1.03    -1.71
muIncrease_taxaInsects                           0.32      1.34    -2.30
muIncrease_taxaMammals                          -0.58      1.32    -3.17
muIncrease_taxaSoundscape                        0.30      1.04    -1.75
muIncrease_habitat_changeloss:taxaBats          -0.53      0.98    -2.49
muIncrease_habitat_changeloss:taxaBirds         -1.00      1.13    -3.21
muIncrease_habitat_changeloss:taxaInsects        0.37      1.31    -2.26
muIncrease_habitat_changeloss:taxaMammals       -0.25      1.45    -3.13
muIncrease_habitat_changeloss:taxaSoundscape    -0.35      1.15    -2.59
                                             u-95% CI Rhat Bulk_ESS Tail_ESS
muDecrease_Intercept                             2.66 1.00     6863     6494
muIncrease_Intercept                             6.23 1.00     5008     5858
muDecrease_habitat_changeloss                    4.26 1.00     4140     5684
muDecrease_taxaBats                              1.33 1.00     7041     5639
muDecrease_taxaBirds                             2.67 1.00     7399     6046
muDecrease_taxaInsects                           2.64 1.00     8807     6234
muDecrease_taxaMammals                           3.52 1.00     9732     6301
muDecrease_taxaSoundscape                        2.50 1.00     6882     5860
muDecrease_habitat_changeloss:taxaBats           2.50 1.00     6520     6211
muDecrease_habitat_changeloss:taxaBirds          2.86 1.00     6448     5504
muDecrease_habitat_changeloss:taxaInsects        2.67 1.00     9397     6465
muDecrease_habitat_changeloss:taxaMammals        3.15 1.00    10648     5657
muDecrease_habitat_changeloss:taxaSoundscape     3.82 1.00     7556     6341
muIncrease_habitat_changeloss                   -0.34 1.00     4720     5793
muIncrease_taxaBats                              1.21 1.00     5833     5699
muIncrease_taxaBirds                             2.36 1.00     6104     6210
muIncrease_taxaInsects                           2.97 1.00    10382     6436
muIncrease_taxaMammals                           1.99 1.00     9646     6331
muIncrease_taxaSoundscape                        2.31 1.00     6536     5994
muIncrease_habitat_changeloss:taxaBats           1.36 1.00     6044     5747
muIncrease_habitat_changeloss:taxaBirds          1.17 1.00     7508     5888
muIncrease_habitat_changeloss:taxaInsects        2.93 1.00     9833     6488
muIncrease_habitat_changeloss:taxaMammals        2.55 1.00    12063     6322
muIncrease_habitat_changeloss:taxaSoundscape     1.94 1.00     7173     5912

Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).
#plot(model)


# Step 5: Get odds ratios (relative to "No effect")
exp(fixef(model))
                                               Estimate Est.Error        Q2.5
muDecrease_Intercept                          1.9486127  2.768437  0.25517823
muIncrease_Intercept                         64.5345205  2.689750 10.04135117
muDecrease_habitat_changeloss                 9.8796560  2.721996  1.42502651
muDecrease_taxaBats                           0.5184553  2.722589  0.07061451
muDecrease_taxaBirds                          1.8379533  2.869572  0.23233086
muDecrease_taxaInsects                        1.1216639  3.662921  0.08728485
muDecrease_taxaMammals                        2.4901810  3.773387  0.18764397
muDecrease_taxaSoundscape                     1.5295680  2.912724  0.18796396
muDecrease_habitat_changeloss:taxaBats        1.7128463  2.736634  0.23730029
muDecrease_habitat_changeloss:taxaBirds       1.9344318  3.020449  0.23563953
muDecrease_habitat_changeloss:taxaInsects     1.0994959  3.682357  0.08447630
muDecrease_habitat_changeloss:taxaMammals     1.3836982  4.170176  0.09149644
muDecrease_habitat_changeloss:taxaSoundscape  4.5074384  3.147112  0.51431748
muIncrease_habitat_changeloss                 0.1111658  2.664680  0.01548713
muIncrease_taxaBats                           0.4821314  2.594262  0.07542094
muIncrease_taxaBirds                          1.3810934  2.800343  0.18068585
muIncrease_taxaInsects                        1.3776320  3.836524  0.09992789
muIncrease_taxaMammals                        0.5586436  3.751260  0.04193968
muIncrease_taxaSoundscape                     1.3435664  2.833921  0.17413969
muIncrease_habitat_changeloss:taxaBats        0.5872509  2.673493  0.08286923
muIncrease_habitat_changeloss:taxaBirds       0.3661487  3.087949  0.04031066
muIncrease_habitat_changeloss:taxaInsects     1.4457496  3.702092  0.10474837
muIncrease_habitat_changeloss:taxaMammals     0.7815792  4.279163  0.04391151
muIncrease_habitat_changeloss:taxaSoundscape  0.7057308  3.169538  0.07478208
                                                   Q97.5
muDecrease_Intercept                          14.2598571
muIncrease_Intercept                         506.8421420
muDecrease_habitat_changeloss                 70.7017067
muDecrease_taxaBats                            3.7859283
muDecrease_taxaBirds                          14.3828250
muDecrease_taxaInsects                        13.9842196
muDecrease_taxaMammals                        33.7248573
muDecrease_taxaSoundscape                     12.1347848
muDecrease_habitat_changeloss:taxaBats        12.1796824
muDecrease_habitat_changeloss:taxaBirds       17.4136226
muDecrease_habitat_changeloss:taxaInsects     14.4123594
muDecrease_habitat_changeloss:taxaMammals     23.3364455
muDecrease_habitat_changeloss:taxaSoundscape  45.7930662
muIncrease_habitat_changeloss                  0.7151615
muIncrease_taxaBats                            3.3437773
muIncrease_taxaBirds                          10.5681699
muIncrease_taxaInsects                        19.5122688
muIncrease_taxaMammals                         7.3511968
muIncrease_taxaSoundscape                     10.1084385
muIncrease_habitat_changeloss:taxaBats         3.9076916
muIncrease_habitat_changeloss:taxaBirds        3.2271011
muIncrease_habitat_changeloss:taxaInsects     18.8199416
muIncrease_habitat_changeloss:taxaMammals     12.8635537
muIncrease_habitat_changeloss:taxaSoundscape   6.9241917
# Step 6: Visualise predicted probabilities
p <- ggpredict(model, terms = c("habitat_change", "taxa"))
plot(p) +
  labs(
    title = "Predicted Probability of Animal Response by Habitat Change and Taxa",
    x = "Habitat Change Type",
    y = "Predicted Probability",
    color = "Taxa"
  ) +
  theme_bw() +
  theme(legend.position = "bottom")

tables

library(kableExtra)
library(dplyr)
library(brms)
library(tibble)

# --- Step 1: Extract and process log-odds ---
logodds_df <- fixef(model) %>%
  as.data.frame() %>%
  rownames_to_column("Parameter") %>%
  rename(
    Estimate = Estimate,
    Std.Error = Est.Error,
    CI_low = Q2.5,
    CI_high = Q97.5
  ) %>%
  mutate(Significant = ifelse(CI_low > 0 | CI_high < 0, TRUE, FALSE))

# --- Step 2: Display full Log-Odds table with bold for significant rows ---
logodds_df %>%
  mutate(across(where(is.numeric), round, 2)) %>%
  kable("html", caption = "Log-Odds Estimates (Logit Scale)", booktabs = TRUE) %>%
  kable_styling(full_width = FALSE, bootstrap_options = c("striped", "hover", "condensed")) %>%
  row_spec(which(logodds_df$Significant), bold = TRUE)
Log-Odds Estimates (Logit Scale)
Parameter Estimate Std.Error CI_low CI_high Significant
muDecrease_Intercept 0.67 1.02 -1.37 2.66 FALSE
muIncrease_Intercept 4.17 0.99 2.31 6.23 TRUE
muDecrease_habitat_changeloss 2.29 1.00 0.35 4.26 TRUE
muDecrease_taxaBats -0.66 1.00 -2.65 1.33 FALSE
muDecrease_taxaBirds 0.61 1.05 -1.46 2.67 FALSE
muDecrease_taxaInsects 0.11 1.30 -2.44 2.64 FALSE
muDecrease_taxaMammals 0.91 1.33 -1.67 3.52 FALSE
muDecrease_taxaSoundscape 0.42 1.07 -1.67 2.50 FALSE
muDecrease_habitat_changeloss:taxaBats 0.54 1.01 -1.44 2.50 FALSE
muDecrease_habitat_changeloss:taxaBirds 0.66 1.11 -1.45 2.86 FALSE
muDecrease_habitat_changeloss:taxaInsects 0.09 1.30 -2.47 2.67 FALSE
muDecrease_habitat_changeloss:taxaMammals 0.32 1.43 -2.39 3.15 FALSE
muDecrease_habitat_changeloss:taxaSoundscape 1.51 1.15 -0.66 3.82 FALSE
muIncrease_habitat_changeloss -2.20 0.98 -4.17 -0.34 TRUE
muIncrease_taxaBats -0.73 0.95 -2.58 1.21 FALSE
muIncrease_taxaBirds 0.32 1.03 -1.71 2.36 FALSE
muIncrease_taxaInsects 0.32 1.34 -2.30 2.97 FALSE
muIncrease_taxaMammals -0.58 1.32 -3.17 1.99 FALSE
muIncrease_taxaSoundscape 0.30 1.04 -1.75 2.31 FALSE
muIncrease_habitat_changeloss:taxaBats -0.53 0.98 -2.49 1.36 FALSE
muIncrease_habitat_changeloss:taxaBirds -1.00 1.13 -3.21 1.17 FALSE
muIncrease_habitat_changeloss:taxaInsects 0.37 1.31 -2.26 2.93 FALSE
muIncrease_habitat_changeloss:taxaMammals -0.25 1.45 -3.13 2.55 FALSE
muIncrease_habitat_changeloss:taxaSoundscape -0.35 1.15 -2.59 1.94 FALSE
# --- Step 3: Compute Odds Ratios and filter significant rows ---
or_df <- logodds_df %>%
  mutate(
    OR = round(exp(Estimate), 2),
    CI_OR_low = round(exp(CI_low), 2),
    CI_OR_high = round(exp(CI_high), 2),
    CI_OR = paste0("[", CI_OR_low, ", ", CI_OR_high, "]"),
    Significant_OR = ifelse(CI_OR_low > 1 | CI_OR_high < 1, TRUE, FALSE)
  )

# --- Step 4: Full Odds Ratios Table with bold for significant ---
# Step 1: Extract coefficients and identify significant ones
significant_results <- fixef(model) %>%
  as.data.frame() %>%
  rownames_to_column("Parameter") %>%
  rename(
    Estimate = Estimate,
    Std.Error = Est.Error,
    CI_low = Q2.5,
    CI_high = Q97.5
  ) %>%
  filter(CI_low > 0 | CI_high < 0)  # significant only

# Step 2: Add readable columns for outcome and habitat change
significant_results_clean <- significant_results %>%
  mutate(
    `Outcome direction` = case_when(
      grepl("^muDecrease", Parameter) ~ "Decrease",
      grepl("^muIncrease", Parameter) ~ "Increase",
      TRUE ~ "Other"
    ),
    `Habitat change` = case_when(
      grepl("habitat_changeloss", Parameter) ~ "Loss",
      grepl("Intercept", Parameter) ~ "Gain",
      TRUE ~ "Interaction or Other"
    )
  ) %>%
  select(`Outcome direction`, `Habitat change`, Estimate, Std.Error, CI_low, CI_high)

# Step 3: Create a kableExtra table
library(kableExtra)

significant_results_clean %>%
  mutate(across(where(is.numeric), round, 2)) %>%
  kable("html", caption = "", booktabs = TRUE) %>%
  kable_styling(full_width = FALSE, bootstrap_options = c("striped", "hover", "condensed"))
Outcome direction Habitat change Estimate Std.Error CI_low CI_high
Increase Gain 4.17 0.99 2.31 6.23
Decrease Loss 2.29 1.00 0.35 4.26
Increase Loss -2.20 0.98 -4.17 -0.34

Methods

Statistical Synthesis (PRISMA 13d)

We conducted a Bayesian multinomial meta-analysis to assess how the type of habitat change (gain or loss) influences the direction of animal responses. This approach allowed us to identify whether there is a systematic pattern in how animal characteristics (such as composition, distribution, ADI, diversity, and richness) change in response to habitat alteration. A Bayesian multinomial logistic regression model was fitted using the brms package (version 2.22.0) within R (version 4.4.3).

We included unique study identifiers (auth.year) as random intercepts, To account for study-level heterogeneity, allowing for variation in baseline effects across studies. The outcome variable was the categorical direction of response, with three levels: “Decrease”, “No effect”, and “Increase”, “No effect” being the reference category for all comparisons. Fixed-effect predictors comprised the habitat change type (gain or loss), taxonomic group, and the interaction between habitat change type and taxonomic group. Additionally, we included drivers of habitat change and response variables as fixed-effect covariates to control for other potential sources of variation.

Heterogeneity

We incorporated Random intercepts for unique studu ID auth.year into the model, explicitly accounting for between-study heterogeneity in baseline response probabilities. We included an interaction term between habitat change type and taxonomic group to test whether the effect of habitat change on animal responses varies across different taxonomic groups. We assessed variation across taxonomic groups by examining the posterior distributions of these interaction terms.

Sensitivity Analyses (PRISMA 13f)

To evaluate the robustness of our synthesised results, we conducted a Prior Sensitivity test. We re-estimated the model using alternative prior distributions (specifically, normal(0, 1) and normal(0, 3) for fixed effects) to assess the influence of prior assumptions on the posterior estimates. The results obtained were consistent with the main findings, indicating robustness to prior specification. The sensitivity did not substantially alter the direction or credibility of the primary effect estimates, reinforcing the robustness of our conclusions.

Results

The analysis included 297 observations from 188 studies.The Bayesian multinomial meta-analysis revealed significant influences of habitat change type on the direction of animal responses, relative to the “No effect” category:

  • Habitat Loss: Habitat loss significantly increased the odds of a Decrease in animal response relative to No effect. Conversely, habitat loss significantly decreased the odds of an Increase in response relative to No effect. This indicates a substantially higher probability of decline in biodiversity indicators associated with habitat loss.

  • Habitat Gain: While we used habitat gain as the reference level, we interpreted its effects from the model intercepts and comparisons. The odds of an Increase in response under habitat gain (relative to No effect) were substantially higher than those observed under habitat loss. Conversely, the odds of a Decrease in response under habitat gain (relative to No effect) were relatively low and associated with higher uncertainty. Overall, these findings suggest that habitat gain significantly increases the probability of biodiversity recovery.

Interaction with Taxonomic Group

Predicted probabilities revealed heterogeneous effects across different taxonomic groups. Specifically, Bats and Birds demonstrated stronger increases under habitat gain when compared to habitat loss, suggesting a more pronounced positive response to restoration or expansion efforts. In contrast, Insects and Soundscapes showed more variable or comparatively weaker responses across habitat change types.

Heterogeneity

We observed substantial between-study heterogeneity. The standard deviation of the random intercepts (τ) for studies was estimated at 2.04 for the “Decrease” outcome (relative to “No effect”) and 2.09 for the “Increase” outcome (relative to “No effect”). This corresponds to an Intraclass Correlation Coefficient (ICC) of 0.55 (95% Credible Interval: [0.38-0.70]), indicating that approximately 55% of the total variance in the direction of animal responses was attributable to differences between studies.