Beta Diversity Functions

Beta diversity is a fundamental concept in ecology that quantifies the variation in species composition between different plots, or over time. In the context of metacommunity analysis, beta diversity functions help to assess how community composition changes spatially across different locations or temporally within a metacommunity.

The beta_diversity functions in MetaCommunityMetrics are adapted from the beta.div.comp function in the R package adespatial. These methods, originally developed by Pierre Legendre (2014), are implemented in Julia to provide a more efficient means of computation for large-scale datasets. The functions use indices from the Podani family, Jaccard-based indices, and Ruzicka-based indices to calculate total beta diversity and its components: replacement and richness difference.

Choosing the Right Function

  • Use beta_diversity for a general, comprehensive measure of beta diversity across your dataset. This function provides an overall assessment of how species composition varies between sites or over time, capturing both replacement (the turnover of species) and richness difference(the difference in species richness).
  • Use spatial_beta_div to comparing diversity between different spatial locations of a metacommunity.
  • Use temporal_beta_div to track how diversity changes over time of a metacommunity.

The Functions

MetaCommunityMetrics.beta_diversityFunction
beta_diversity(mat::Matrix; quant::Bool) -> DataFrame

Calculate beta diversity for a given biodiversity data. This function supports both binary (presence/absence) and quantitative data.

Arguments

  • mat::Matrix: A matrix where each row represents a sample and each column represents a species. The elements of the matrix should represent the presence/absence or abundance of species.
  • quant::Bool: A boolean flag that specifies whether the data is quantitative. By default, it is set to false, which means the data will be treated as binary. In this case, any quantitative data will be converted to binary, and beta diversity is calculated using the Podani family’s Jaccard-based indices. If true, the data is treated as quantitative, and beta diversity is calculated using the Podani family’s Ruzicka-based indices. For binary data, quant must remain set to false.

Returns

  • DataFrame: A DataFrame with the following columns:
    • BDtotal: Total beta diversity, which captures the overall dissimilarity between local communities.
    • Repl: Replacement component of diversity, which reflects how many species are different in one site compared to another, ignoring the species that are mere additions or subtractions.
    • RichDif: Richness difference component of diversity, which captures the disparity in biodiversity in terms of the count of species present, without taking into account the specific identities or distributions of those species.

Details

  • Empty patches have to be removed before calculation.
  • Species that were not recorded at the given time step have to be removed before calculation.
  • For binary data, the function calculates Podani family, Jaccard-based indices.
  • For quantitative data, the function calculates Podani family, Ruzicka-based indices.
  • This function is a translation/adaptation of the beta.dov.comp function from the R package adespatial,licensed under GPL-3.
  • Original package and documentation available at: https://cran.r-project.org/web/packages/adespatial/index.html

Example

julia> using MetaCommunityMetrics, Pipe, DataFrames

julia> df = load_sample_data()
48735×10 DataFrame
   Row │ Year   Month  Day    Sampling_date_order  plot   Species  Abundance  Presence  Latitude  Longitude 
       │ Int64  Int64  Int64  Int64                Int64  String3  Int64      Int64     Float64   Float64   
───────┼────────────────────────────────────────────────────────────────────────────────────────────────────
     1 │  2010      1     16                    1      1  BA               0         0      35.0     -110.0
     2 │  2010      1     16                    1      2  BA               0         0      35.0     -109.5
     3 │  2010      1     16                    1      8  BA               0         0      35.5     -109.5
     4 │  2010      1     16                    1      9  BA               0         0      35.5     -109.0
     5 │  2010      1     16                    1     11  BA               0         0      35.5     -108.0
   ⋮   │   ⋮      ⋮      ⋮             ⋮             ⋮       ⋮         ⋮         ⋮         ⋮          ⋮
 48731 │  2023      3     21                  117      9  SH               0         0      35.5     -109.0
 48732 │  2023      3     21                  117     10  SH               0         0      35.5     -108.5
 48733 │  2023      3     21                  117     12  SH               1         1      35.5     -107.5
 48734 │  2023      3     21                  117     16  SH               0         0      36.0     -108.5
 48735 │  2023      3     21                  117     23  SH               0         0      36.5     -108.0
                                                                                          48725 rows omitted

julia> matrix_with_abundance =  @pipe df |>
           filter(row -> row[:Sampling_date_order] == 1, _) |> 
           select(_, Not(:Presence)) |>
           unstack(_, :Species, :Abundance, fill=0) |>
           select(_, Not(:Year, :Month, :Day, :Sampling_date_order, :plot, :Longitude, :Latitude)) |> 
           Matrix(_) |> 
           x -> x[:, sum(x, dims=1)[1, :] .!= 0] |> 
           x -> x[vec(sum(x, dims=2)) .!= 0, :]
15×5 Matrix{Int64}:
 1  0  0  0  0
 1  0  0  0  0
 1  0  0  0  0
 2  0  0  0  0
 1  0  0  1  0
 4  0  0  1  0
 1  0  0  0  0
 0  1  0  0  1
 0  0  0  1  0
 0  0  0  2  0
 1  0  0  0  0
 0  0  0  1  0
 0  0  0  0  1
 0  0  1  0  0
 0  0  0  0  1

julia> matrix_with_presence = @pipe df |> 
           filter(row -> row[:Sampling_date_order] == 1, _) |> 
           select(_, Not(:Abundance)) |>
           unstack(_, :Species, :Presence, fill=0) |> #convert it back to the wide format 
           select(_, Not(:Year, :Month, :Day, :Sampling_date_order, :plot, :Longitude, :Latitude)) |> 
           Matrix(_) |>     
           x -> x[:, sum(x, dims=1)[1, :] .!= 0]
15×5 Matrix{Int64}:
 1  0  0  0  0
 1  0  0  0  0
 1  0  0  0  0
 1  0  0  0  0
 1  0  0  1  0
 1  0  0  1  0
 1  0  0  0  0
 0  1  0  0  1
 0  0  0  1  0
 0  0  0  1  0
 1  0  0  0  0
 0  0  0  1  0
 0  0  0  0  1
 0  0  1  0  0
 0  0  0  0  1

julia> result_using_abanduce_data_1 = beta_diversity(matrix_with_abundance; quant=true)
1×3 DataFrame
 Row │ BDtotal   Repl     RichDif  
     │ Float64   Float64  Float64  
─────┼─────────────────────────────
   1 │ 0.390317   0.2678  0.122517

julia> result_using_abanduce_data_2 = beta_diversity(matrix_with_abundance; quant=false)
1×3 DataFrame
 Row │ BDtotal   Repl      RichDif   
     │ Float64   Float64   Float64   
─────┼───────────────────────────────
   1 │ 0.357143  0.284127  0.0730159

julia> result_using_binary_data = beta_diversity(matrix_with_presence; quant=false)
1×3 DataFrame
 Row │ BDtotal   Repl      RichDif   
     │ Float64   Float64   Float64   
─────┼───────────────────────────────
   1 │ 0.357143  0.284127  0.0730159
source
MetaCommunityMetrics.spatial_beta_divFunction
spatial_beta_div(abundance::AbstractVector, time::AbstractVector, patch::Union{AbstractVector, String}, species::Union{AbstractVector, String}; quant::Bool) -> DataFrame

Calculate the beta diversity decompositions of a metacommunity in space based on species abundances or presence-absences using the function beta_diversity.

Arguments

  • abundance::Vector: A vector containing abundance data for each species across different samples.
  • time::Vector: A vector indicating the time each sample was taken.
  • patch::Vector: A vector indicating the spatial location (patch) of each sample.
  • species::Vector: A vector indicating the species associated with each abundance entry.
  • quant::Bool: A boolean flag that specifies whether the data is quantitative. By default, it is set to false, which means the data will be treated as binary. In this case, any quantitative data will be converted to binary, and beta diversity is calculated using the Podani family’s Jaccard-based indices. If true, the data is treated as quantitative, and beta diversity is calculated using the Podani family’s Ruzicka-based indices. For binary data, quant must remain set to false.

Returns

  • DataFrame: A DataFrame containing the values of total beta diversity, replacement, and richness difference components in space. Columns are spatial_BDtotal, spatial_Repl, and spatial_RichDif.

Details

  • This function uses the beta_diversity function to calculate beta diversity components after aggregating .
  • For binary data, the function calculates Podani family, Jaccard-based indices.
  • For quantitative data, the function calculates Podani family, Ruzicka-based indices.
  • The beta diversity decompositions of a metacommunity in space is a set of metrics suggested by Guzman et al. (2022) to infer metacommunity processes.

Example

julia> using MetaCommunityMetrics, Pipe, DataFrames

julia> df = load_sample_data()
48735×10 DataFrame
   Row │ Year   Month  Day    Sampling_date_order  plot   Species  Abundance  Presence  Latitude  Longitude 
       │ Int64  Int64  Int64  Int64                Int64  String3  Int64      Int64     Float64   Float64   
───────┼────────────────────────────────────────────────────────────────────────────────────────────────────
     1 │  2010      1     16                    1      1  BA               0         0      35.0     -110.0
     2 │  2010      1     16                    1      2  BA               0         0      35.0     -109.5
     3 │  2010      1     16                    1      8  BA               0         0      35.5     -109.5
     4 │  2010      1     16                    1      9  BA               0         0      35.5     -109.0
     5 │  2010      1     16                    1     11  BA               0         0      35.5     -108.0
   ⋮   │   ⋮      ⋮      ⋮             ⋮             ⋮       ⋮         ⋮         ⋮         ⋮          ⋮
 48731 │  2023      3     21                  117      9  SH               0         0      35.5     -109.0
 48732 │  2023      3     21                  117     10  SH               0         0      35.5     -108.5
 48733 │  2023      3     21                  117     12  SH               1         1      35.5     -107.5
 48734 │  2023      3     21                  117     16  SH               0         0      36.0     -108.5
 48735 │  2023      3     21                  117     23  SH               0         0      36.5     -108.0
                                                                                          48725 rows omitted

julia> result_using_abanduce_data_1 = spatial_beta_div(df.Abundance, df.Sampling_date_order, df.plot, df.Species; quant=true)
1×3 DataFrame
 Row │ spatial_BDtotal  spatial_Repl  spatial_RichDif 
     │ Float64          Float64       Float64         
─────┼────────────────────────────────────────────────
   1 │        0.264822      0.121882         0.142939
        
julia> result_using_abanduce_data_2 = spatial_beta_div(df.Abundance, df.Sampling_date_order, df.plot, df.Species; quant=false)
1×3 DataFrame
 Row │ spatial_BDtotal  spatial_Repl  spatial_RichDif 
     │ Float64          Float64       Float64         
─────┼────────────────────────────────────────────────
   1 │        0.133035       0.05976        0.0732746

julia> result_using_binary_data = spatial_beta_div(df.Presence, df.Sampling_date_order, df.plot, df.Species; quant=false)
1×3 DataFrame
 Row │ spatial_BDtotal  spatial_Repl  spatial_RichDif 
     │ Float64          Float64       Float64         
─────┼────────────────────────────────────────────────
   1 │        0.133035       0.05976        0.0732746
source
MetaCommunityMetrics.temporal_beta_divFunction
temporal_beta_div(abundance::AbstractVector, time::AbstractVector, patch::Union{AbstractVector, String}, species::Union{AbstractVector, String};quant::Bool) -> DataFrame

Calculate the beta diversity decompositions of a metacommunity in time based on species abundances or presence-absences using the function beta_diversity.

Arguments

  • abundance::Vector: A vector containing abundance data for each species across different samples.
  • time::Vector: A vector indicating the time each sample was taken.
  • patch::Vector: A vector indicating the spatial location (patch) of each sample.
  • species::Vector: A vector indicating the species associated with each abundance entry.
  • quant::Bool: A boolean flag that specifies whether the data is quantitative. By default, it is set to false, which means the data will be treated as binary. In this case, any quantitative data will be converted to binary, and beta diversity is calculated using the Podani family’s Jaccard-based indices. If true, the data is treated as quantitative, and beta diversity is calculated using the Podani family’s Ruzicka-based indices. For binary data, quant must remain set to false.

Returns

  • DataFrame: A DataFrame containing the values of total beta diversity, replacement, and richness difference components in time. Columns are temporal_BDtotal, temporal_Repl, and temporal_RichDif.

Details

  • This function uses the beta_diversity function to calculate beta diversity components for each patch.
  • For binary data, the function calculates Podani family, Jaccard-based indices.
  • For quantitative data, the function calculates Podani family, Ruzicka-based indices.
  • The beta diversity decompositions of a metacommunity in time is a set of metrics suggested by Guzman et al. (2022) to infer metacommunity processes.

Example

julia> using MetaCommunityMetrics, Pipe, DataFrames

julia> df = load_sample_data()
48735×10 DataFrame
   Row │ Year   Month  Day    Sampling_date_order  plot   Species  Abundance  Presence  Latitude  Longitude 
       │ Int64  Int64  Int64  Int64                Int64  String3  Int64      Int64     Float64   Float64   
───────┼────────────────────────────────────────────────────────────────────────────────────────────────────
     1 │  2010      1     16                    1      1  BA               0         0      35.0     -110.0
     2 │  2010      1     16                    1      2  BA               0         0      35.0     -109.5
     3 │  2010      1     16                    1      8  BA               0         0      35.5     -109.5
     4 │  2010      1     16                    1      9  BA               0         0      35.5     -109.0
     5 │  2010      1     16                    1     11  BA               0         0      35.5     -108.0
   ⋮   │   ⋮      ⋮      ⋮             ⋮             ⋮       ⋮         ⋮         ⋮         ⋮          ⋮
 48731 │  2023      3     21                  117      9  SH               0         0      35.5     -109.0
 48732 │  2023      3     21                  117     10  SH               0         0      35.5     -108.5
 48733 │  2023      3     21                  117     12  SH               1         1      35.5     -107.5
 48734 │  2023      3     21                  117     16  SH               0         0      36.0     -108.5
 48735 │  2023      3     21                  117     23  SH               0         0      36.5     -108.0
                                                                                          48725 rows omitted

julia> result_using_abanduce_data_1 = temporal_beta_div(df.Abundance, df.Sampling_date_order, df.plot, df.Species; quant=true)
1×3 DataFrame
 Row │ temporal_BDtotal  temporal_Repl  temporal_RichDif 
     │ Float64           Float64        Float64          
─────┼───────────────────────────────────────────────────
   1 │         0.311222      0.0995483          0.211674
        
julia> result_using_abanduce_data_2 = temporal_beta_div(df.Abundance, df.Sampling_date_order, df.plot, df.Species; quant=false)
1×3 DataFrame
 Row │ temporal_BDtotal  temporal_Repl  temporal_RichDif 
     │ Float64           Float64        Float64          
─────┼───────────────────────────────────────────────────
   1 │         0.206262      0.0693664          0.136895

julia> result_using_binary_data = temporal_beta_div(df.Presence, df.Sampling_date_order, df.plot, df.Species; quant=false)
1×3 DataFrame
 Row │ temporal_BDtotal  temporal_Repl  temporal_RichDif 
     │ Float64           Float64        Float64          
─────┼───────────────────────────────────────────────────
   1 │         0.206262      0.0693664          0.136895
source

References

  • Guzman, L. M. et al. Accounting for temporal change in multiple biodiversity patterns improves the inference of metacommunity processes. Ecology 103, e3683 (2022). https://doi.org:https://doi.org/10.1002/ecy.3683
  • Legendre, P. Interpreting the replacement and richness difference components of beta diversity. Global Ecology and Biogeography 23, 1324-1334 (2014). https://doi.org:https://doi.org/10.1111/geb.12207