Overview

This notebook summarises the main outputs of the Dirichlet–multinomial JSDM, focusing on (i) species-level environmental responses, (ii) overlap of responses across scales, and (iii) community-level variance partitioning.

Species-level responses

Code
Summary_beta <- vroom::vroom(here_rel("results", "models", "H1", "beta_fitH1.tsv.gz")) |>
    mutate(
        # significance at 80% CI
        sig80 = (l > 0 & h > 0) | (l < 0 & h < 0),
        sign = case_when(
            sig80 & m > 0 ~ "positive",
            sig80 & m < 0 ~ "negative",
            TRUE ~ "ns"
        )
    )
## Rows: 9104 Columns: 10
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: "\t"
## chr (5): variable, Scale, parameter, genus, species
## dbl (5): m, ll, l, h, hh
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Species-level environmental preferences are summarised from posterior draws of species-specific coefficients. We classify an effect as “significant” when the 80% credible interval excludes zero.

Significant species reponses across scales

Code
rbind(
    Summary_beta |>
        filter(Scale %in% c("Regional", "Landscape", "Local")) |>
        group_by(genus, species) |>
        summarise(scale_sig = any(sig80)) |>
        ungroup() |>
        summarise(
            n_sig = sum(scale_sig),
            per_sig = sum(scale_sig) / 569
        ) |>
        mutate(
            Scale = "All",
            parameter = "-",
            n_pos = "-",
            per_pos = "-",
            n_neg = "-",
            per_neg = "-",
        ),
    Summary_beta |>
        filter(Scale %in% c("Regional", "Landscape")) |>
        group_by(Scale, genus, species) |>
        summarise(scale_sig = any(sig80)) |>
        group_by(Scale) |>
        summarise(
            n_sig = sum(scale_sig),
            per_sig = sum(scale_sig) / 569
        ) |>
        mutate(
            parameter = "All",
            n_pos = "-",
            per_pos = "-",
            n_neg = "-",
            per_neg = "-",
        ),
    Summary_beta |>
        filter(Scale %in% c("Regional", "Landscape", "Local")) |>
        mutate(parameter = if_else(Scale == "Landscape", paste0("GeomSub", str_pad(gsub("GeomSub", "", parameter),
            width = 2,
            side = "left", pad = "0"
        )), parameter)) |>
        group_by(Scale, parameter, genus, species) |>
        summarise(scale_sig = any(sig80), scale_pos = (sign == "positive"), scale_neg = (sign == "negative")) |>
        group_by(Scale, parameter) |>
        summarise(
            n_sig = sum(scale_sig),
            per_sig = round(sum(scale_sig) / 569, digits = 3),
            n_pos = sum(scale_pos),
            per_pos = round(sum(scale_pos) / 569, digits = 3),
            n_neg = sum(scale_neg),
            per_neg = round(sum(scale_neg) / 569, digits = 3)
        )
) |>
    select(Scale, parameter, per_sig, n_pos, per_pos, n_sig, per_neg, n_neg) |>
    arrange(match(Scale, c("All", "Regional", "Landscape", "Local")), parameter) |>
    rename(
        "Parameters" = "parameter",
        "Non-null" = "per_sig",
        "Positif" = "per_pos",
        "Negatif" = "per_neg"
    ) |>
    gt(groupname_col = "Scale") |>
    cols_label(Scale = "") |>
    cols_align("left", Scale) |>
    fmt_number(columns = c("Non-null", "Positif", "Negatif"), decimals = 3) |>
    cols_merge(
        columns = c("Non-null", "n_sig"),
        pattern = "<<{1}>><< [{2}]>>"
    ) |>
    cols_merge(
        columns = c("Positif", "n_pos"),
        pattern = "<<{1}>><< [{2}]>>"
    ) |>
    cols_merge(
        columns = c("Negatif", "n_neg"),
        pattern = "<<{1}>><< [{2}]>>"
    ) |>
    tab_spanner(
        label = "Significant species' responses (%[count])",
        columns = c("Non-null", "Positif", "Negatif")
    ) |>
    tab_source_note(
        source_note = md(
            "Proportion and counts of the 569 analysed tree and palm species showing a significant non-zero response to each predictor (80% credible interval).
            Predictors are grouped by scale where '**regional**' gathers the MFPCA axes, '**landscapes**' gather the geomorphological subtypes , and '**local**' reports the Topographic Wetness Index effect."
        )
    ) |>
    opts_theme()
## `summarise()` has regrouped the output.
## `summarise()` has regrouped the output.
## `summarise()` has regrouped the output.
## `summarise()` has regrouped the output.
## ℹ Summaries were computed grouped by genus and species.
## ℹ Output is grouped by genus.
## ℹ Use `summarise(.groups = "drop_last")` to silence this message.
## ℹ Use `summarise(.by = c(genus, species))` for per-operation grouping
##   (`?dplyr::dplyr_by`) instead.
Percentage and count of significant environmental preferences (IC80%).
Parameters
Significant species' responses (%[count])
Non-null Positif Negatif
All
- 0.993 [565] - [-] - [-]
Regional
All 0.831 [473] - [-] - [-]
Clim1 0.633 [360] 0.452 [257] 0.181 [103]
Clim2 0.582 [331] 0.193 [110] 0.388 [221]
Landscape
All 0.942 [536] - [-] - [-]
GeomSub02 0.594 [338] 0.371 [211] 0.223 [127]
GeomSub03 0.148 [84] 0.074 [42] 0.074 [42]
GeomSub04 0.162 [92] 0.125 [71] 0.037 [21]
GeomSub05 0.056 [32] 0.046 [26] 0.011 [6]
GeomSub06 0.346 [197] 0.186 [106] 0.16 [91]
GeomSub07 0.329 [187] 0.206 [117] 0.123 [70]
GeomSub08 0.074 [42] 0.062 [35] 0.012 [7]
GeomSub09 0.214 [122] 0.162 [92] 0.053 [30]
GeomSub10 0.005 [3] 0.004 [2] 0.002 [1]
GeomSub11 0.149 [85] 0.125 [71] 0.025 [14]
GeomSub12 0.392 [223] 0.209 [119] 0.183 [104]
GeomSub13 0.158 [90] 0.086 [49] 0.072 [41]
Local
logSWI 0.378 [215] 0.095 [54] 0.283 [161]
Proportion and counts of the 569 analysed tree and palm species showing a significant non-zero response to each predictor (80% credible interval). Predictors are grouped by scale where ‘regional’ gathers the MFPCA axes, ‘landscapes’ gather the geomorphological subtypes , and ‘local’ reports the Topographic Wetness Index effect.

Overall

Of the 569 species analysed, 565 (99.3%) exhibited a significant response (\(IC_{80\%}\)), to at least one variable belonging to studied scales (regional climate, geomorphological landscape, or local topography), whereas 4 species (0.7%) showed no detectable association with the tested predictors.

Regional climate

Overall, 83.1% of species showed at least one significant response to the climatic predictors. The “inland-to-coast” axis Clim1 affected a larger fraction of species (63.3% of species) than the “west-to-east” axis Clim2 (58.2% of species).

Geomorphological landscapes

Responses to geomorphological landscapes were widespread across 94.2% of species, which responded to at least one landscape subtype. High heterogeneity in significant response frequency was noticeable across geomorphological landscape where frequency decreased from “coastal plains” (63.3%, \(GeomSub_{[2-3]}\)) and “multiconvex reliefs” (61.0%, \(GeomSub_{[6-9]}\)), followed by “high relief” areas (47.8%, \(GeomSub_{[12-13]}\)), and to the least frequently associated landscape in “multiconcave reliefs” (19.3%, \(GeomSub_{[4-5]}\)) and “plateaux” (15.3%, \(GeomSub_{[10-11]}\)). In particular, the “\(GeomSub_{10}\) very moderate plateau” subtype showed very few associations (0.5%). Subtypes dominated by sandy substrates (e.g., “ coastal white sands (\(GeomSub_{3}\))”; “ Inland plain with (\(GeomSub_{4}\)) or without (\(GeomSub_{5}\)) residual relief”) yielded fewer than 20% associations within the selected species pool. Within-group contrasts were marked with, for instance, “coastal plains” landscapes where “\(GeomSub_{2}\) plains with residual relief” yielded 59.4% significant responses, whereas “\(GeomSub_{3}\) coastal white sands” showed only 14.8%.

Local topography

37.8% of species responded to the SWI, more with negative effects (28.3%) than positive effects (9.5%), indicating lower occurrence for many species for wetter topographic positions (high SWI) particularly found in bottomlands and topographic ridges within plateaus.

Correlations between species reponses

Code

if (!file.exists(here_rel("notebook", "figs", "corrplot_betas.png"))) {
    # mat : matrice de donnée
    # ... : Arguments supplémentaire à passer à la fonction cor.test
    cor.mtest <- function(mat, ...) {
        mat <- as.matrix(mat)
        n <- ncol(mat)
        p.mat <- matrix(NA, n, n)
        diag(p.mat) <- 0
        for (i in 1:(n - 1)) {
            for (j in (i + 1):n) {
                tmp <- cor.test(mat[, i], mat[, j], ...)
                p.mat[i, j] <- p.mat[j, i] <- tmp$p.value
            }
        }
        colnames(p.mat) <- rownames(p.mat) <- colnames(mat)
        p.mat
    }

    beta_corr <- Summary_beta |>
        filter(Scale %in% c("Regional", "Landscape", "Local")) |>
        mutate(parameter = if_else(Scale == "Landscape", paste0("GeomSub", str_pad(gsub("GeomSub", "", parameter),
            width = 2,
            side = "left", pad = "0"
        )), parameter)) |>
        mutate(GS = paste(genus, species)) |>
        select(GS, parameter, m) |>
        pivot_wider(names_from = parameter, values_from = m) |>
        select(-GS) |>
        select(c("Clim1", "Clim2", paste0("GeomSub", str_pad(2:13,
            width = 2,
            side = "left", pad = "0"
        )), "logSWI"))

    p.mat <- cor.mtest(beta_corr)

    g <- ggcorrplot2::ggcorrplot(cor(beta_corr),
        insig = "label_sig",
        p.mat = p.mat, type = "upper", show.diag = FALSE
    )

    ggsave(plot = g, filename = here_rel("notebook", "figs", "corrplot_betas.png"), bg = "white", width = 10, height = 10, dpi = 1500)
}

knitr::include_graphics(here_rel("notebook", "figs", "corrplot_betas.png"))
Figure 1: Pearson correlations (r) among species-level environmental preference coefficients for 569 species.

Within scale

We found a negative intra-scale correlation between species-level coefficients for Clim1 and Clim2 (\(r = −0.43\)). Coefficients of geomorphological landscape preference showed weak but significant positive correlations among “multiconcave”- \(GeomSub_{[4-5]}\) (\(r = 0.19\)), “multiconvex”- \(GeomSub_{[6-9]}\) (\(r[0.21,0.27]\)), and “high relief” - \(GeomSub_{[12-13]}\) classes (\(r = 0.24\)). In contrast, “high plateaus” - \(GeomSub_{[12-13]}\) were negatively correlated with “coastal” - \(GeomSub_{[2-3]}\) subtypes(\(r[-0.25,-0.19]\)), “multiconcave reliefs” - \(GeomSub_{[4-5]}\) (\(r[-0.13,-0.08]\)), “high reliefs” - \(GeomSub_{[12-13]}\) (\(r[-0.11,-0.08]\)), and with the “multiconvex” - \(GeomSub_{[6-9]}\) landscape (“low hills” - \(GeomSub_{[6]}\) \(r = -0.15\) ; “regular hills” - \(GeomSub_{[9]}\) \(r = -0.20\)).

Across scale

Cross-scale correlations of species preferences were present with a positive Clim2-SWI correlation, and the “multiconvex”- \(GeomSub_{[6-9]}\) landscape positively correlated with Clim1 and negatively with Clim2 and SWI (Figure 1).

Overlap of significant responses across scales

We summarise whether each species shows at least one significant effect for each scale, then visualise overlaps.

Code
if (!file.exists(here_rel("notebook", "figs", "overlap_beta.png"))) {
    # Species significant for climate if at least one of Clim1/Clim2 is significant
    beta_scales <- Summary_beta |>
        filter(Scale %in% c("Regional", "Landscape", "Local")) |>
        mutate(parameter = if_else(Scale == "Landscape", paste0("GeomSub", str_pad(gsub("GeomSub", "", parameter),
            width = 2,
            side = "left", pad = "0"
        )), parameter)) |>
        mutate(GS = paste0(genus, species))

    clim_set <- beta_scales |>
        filter(parameter %in% c("Clim1", "Clim2")) |>
        group_by(GS) |>
        summarise(any_sig = any(sig80), .groups = "drop") |>
        filter(any_sig) |>
        pull(GS)

    swi_set <- beta_scales |>
        filter(parameter == "logSWI", sig80) |>
        pull(GS) |>
        unique()

    geom_set <- beta_scales |>
        filter(Scale == "Landscape") |>
        group_by(GS) |>
        summarise(any_sig = any(sig80), .groups = "drop") |>
        filter(any_sig) |>
        pull(GS)

    # Tibble format
    sets_tibble <- tibble(
        GS = unique(beta_scales$GS),
        Regional.Climate = GS %in% clim_set,
        Geomorphological.Landscapes = GS %in% geom_set,
        Local.Topography = GS %in% swi_set
    ) |> select(-GS)

    g <- ggvenn::ggvenn(sets_tibble, stroke_size = 0.5, set_name_size = 5, fill_color = c("red", "brown", "blue"), fill_alpha = 0.1, show_outside = "always")

    ggsave(plot = g, filename = here_rel("notebook", "figs", "overlap_beta.png"), bg = "white", width = 10, height = 10, dpi = 1500)
}

knitr::include_graphics(here_rel("notebook", "figs", "overlap_beta.png"))
Figure 2: Percentage of significant climatic, geomorphological landscape, and local topographic effects across species.

Species preferences were defined as a multi-scale response to environment (Figure 2). 46.9% of species showed significant effects of both regional climate and geomorphological landscape effects, and 31.3% responded significantly to all three filters. Single-scale significant affinities were rare (geomorphological landscape only: 10.9%; regional climate only: 3.7%; local topography only: 0.2%), and 0.7% showed no significant effect of any tested variables.