W06 Small Populations

Author

Diana Robledo, Peter Unmack

Published

March 9, 2026

W06 Management of Small Populations

Managing small populations: genetics and conservation

Prerequisites

Small and fragmented populations are one of the most common challenges in conservation biology. Habitat loss and landscape fragmentation frequently interrupt natural gene flow, leaving species divided into small isolated populations. In such populations, evolutionary processes such as genetic drift and inbreeding become dominant forces, often leading to reduced genetic diversity, inbreeding depression, and ultimately increased extinction risk. >>>>>>> main

Modern conservation management therefore increasingly incorporates genetic information to diagnose population fragmentation, evaluate genetic erosion, and design interventions that restore gene flow. One important strategy is genetic rescue, the deliberate increase of gene flow between populations to reduce inbreeding and restore genetic diversity.

In this session we introduce the genetic processes affecting small populations and outline a practical framework used by conservation geneticists to assess whether populations are genetically threatened and when interventions such as assisted gene flow may be appropriate. The tutorial component will demonstrate how genomic data can be used to diagnose fragmentation, estimate genetic diversity, and support management decisions.

Learning outcomes

By the end of this session you should be able to:

  • explain why small and isolated populations are particularly vulnerable to genetic drift and inbreeding
  • describe how habitat fragmentation disrupts gene flow
  • recognise the genetic consequences of small population size, including loss of diversity and inbreeding depression
  • outline the concept of genetic rescue and when it may be beneficial
  • interpret basic genetic analyses used to diagnose genetic erosion and population structure
  • understand how genomic data can support evidence-based conservation management

Session summary

Human-driven habitat fragmentation has created many small and isolated populations across the globe. In these populations, genetic drift increases inbreeding and reduces genetic diversity, limiting adaptive potential and increasing extinction risk.

Conservation genetics provides tools to diagnose these problems and guide management responses. A key approach is genetic rescue, which restores gene flow between populations to alleviate inbreeding depression and increase genetic diversity. Although risks such as outbreeding depression must be considered, evidence shows that genetic rescue is often highly beneficial when populations are small and isolated.

Effective genetic management therefore requires a structured process:
1. Diagnose genetic erosion using genetic diversity, inbreeding, and population structure.
2. Evaluate potential donor populations for increasing gene flow.
3. Assess risks such as outbreeding depression.
4. Implement and monitor genetic management actions.

Genomic data combined with clear decision frameworks allow conservation practitioners to make informed management decisions that increase the long-term viability of threatened populations.

Worked Example

Required packges

library(dartRverse)
***********************************************
**** Welcome to dartRverse [Version 1.2.2] ****
***********************************************
── Core dartRverse packages ────────────────────────────────────── dartRverse ──
✔ dartR.base 1.2.2     ✔ dartR.data 1.2.2
── Installed dartRverse packages   ─────────────────────────────── dartRverse ──
✔ dartR.captive   1.2.2     ✔ dartR.sim       1.2.2
✔ dartR.popgen    1.2.2     ✔ dartR.spatial   1.2.2
✔ dartR.sexlinked 1.2.2     
library(future)
library(future.apply)

Step 1: Read the data

#read the data
gl <- readRDS("data/mog.adspersa.dartr.rdata")

Step 2: Select the relevant predefined samples

index <- gl@other$ind.metrics$mdb_mix =="Darling"
gl <- gl[ index, ]

Step 3: Filter the data

#first eliminate monomorphs
gl <- gl.filter.monomorphs(gl, verbose=3)
Starting gl.filter.monomorphs 
  Processing genlight object with SNP data
  Warning: data include loci that are scored NA across all individuals.
  Consider filtering using gl <- gl.filter.allna(gl)
  Identifying monomorphic loci
  Removing monomorphic loci and loci with all missing 
                       data
    Original No. of loci: 12908 
    Monomorphic loci: 9228 
    Loci scored all NA: 744 
    No. of loci deleted: 9228 
    No. of loci retained: 3680 
    No. of individuals: 102 
    No. of populations: 5 
Completed: gl.filter.monomorphs 
#filter loci callrate (individuals with low call rates have already been removed)
gl <- gl.filter.callrate(gl, method = "loc", threshold=0.95, verbose=3)
Starting gl.filter.callrate 
  Processing genlight object with SNP data
  Recalculating Call Rate
  Removing loci based on Call Rate, threshold = 0.95 
  Summary of filtered dataset
    Call Rate for loci > 0.95 
    Original No. of loci : 3680 
    Original No. of individuals: 102 
    No. of loci retained: 3003 
    No. of individuals retained: 102 
    No. of populations:  5 

Completed: gl.filter.callrate 
#to visualise the frequency of rare alleles
gl.sfs(gl, singlepop = T)
Starting gl.sfs 
  Processing genlight object with SNP data
Your data contains missing data, better filter stronger or use gl.impute to fill those gaps meaningful!

Completed: gl.sfs 
  d0   d1   d2   d3   d4   d5   d6   d7   d8   d9  d10  d11  d12  d13  d14  d15 
   0 1554  423  209   89   77   24   35   22   19   15   15    9    7   10    6 
 d16  d17  d18  d19  d20  d21  d22  d23  d24  d25  d26  d27  d28  d29  d30  d31 
   8    8    7    6    9    7    2    7   11    8    8    9    9   13    6    3 
 d32  d33  d34  d35  d36  d37  d38  d39  d40  d41  d42  d43  d44  d45  d46  d47 
   9    8   37   12   12    5    6    4    9    7    8   10    5    6    6    3 
 d48  d49  d50  d51  d52  d53  d54  d55  d56  d57  d58  d59  d60  d61  d62  d63 
   6    1    4    4    4    5    3    8    5    6    6    2    7    9    6    4 
 d64  d65  d66  d67  d68  d69  d70  d71  d72  d73  d74  d75  d76  d77  d78  d79 
   5    4    3    4    2    6    4    3    4    3    4    3    4    9    8    8 
 d80  d81  d82  d83  d84  d85  d86  d87  d88  d89  d90  d91  d92  d93  d94  d95 
   2    4    4    5    2    1    5    4    1    1    4    6    2    1    7    4 
 d96  d97  d98  d99 d100 d101 d102 
   2    2    1    4    4    0    1 
#Filter rare alleles, a value of three removes any alleles present in only one or two individuals
gl <- gl.filter.maf(gl, threshold = 3, v=3)
Starting gl.filter.maf 
  Processing genlight object with SNP data
  Removing loci with MAF < 0.0147058823529412 over all the dataset
                and recalculating FreqHoms and FreqHets
  Summary of filtered dataset
  MAF for loci > 0.01470588 
  Initial number of loci: 3003 
  Number of loci deleted: 2073 
  Final number of loci: 930 

Completed: gl.filter.maf 

Step 4: Run and export the mixing results, this versions takes the “optimal” individual first, note that ncores may need to be adjusted to the number of cores you have available on your computer, I normally choose N-1

On this Posit Cloud we only have 2 cores, PLEASE DON’T CHANGE THE NUMBER OF CORES

system.time(yy <- gl.opt.ind.all(gl, ncores=2, first="optimal", plot = T))

   user  system elapsed 
   0.56    0.02    0.58 
write.csv(yy, file="mog.test1a.csv", row.names=F)

Re-run the code, this time evening samples sizes per population to 14

Read the data, select the relevant predefined samples

gl <- readRDS("data/mog.adspersa.dartr.rdata")
index <- gl@other$ind.metrics$mdb_mix =="Darling"
gl <- gl[ index, ]

Reduces each population to the n= value with no replacement

gl <- gl.subsample.ind2 (gl, n = 14, replace = FALSE)
Starting gl.subsample.ind2 
  Processing genlight object with SNP data
  Warning: data include loci that are scored NA across all individuals.
  Consider filtering using gl <- gl.filter.allna(gl)
  Warning: The parameter method is deprecated, no longer required  Warning: The parameter method is deprecated, no longer required  Warning: The parameter method is deprecated, no longer required  Warning: The parameter method is deprecated, no longer requiredCompleted: gl.subsample.ind2 
gl <- gl.filter.monomorphs(gl, v=3)
Starting gl.filter.monomorphs 
  Processing genlight object with SNP data
  Warning: data include loci that are scored NA across all individuals.
  Consider filtering using gl <- gl.filter.allna(gl)
  Identifying monomorphic loci
  Removing monomorphic loci and loci with all missing 
                       data
    Original No. of loci: 12908 
    Monomorphic loci: 9976 
    Loci scored all NA: 867 
    No. of loci deleted: 9976 
    No. of loci retained: 2932 
    No. of individuals: 70 
    No. of populations: 5 
Completed: gl.filter.monomorphs 
gl <- gl.filter.callrate(gl, method = "loc", threshold=0.95, verbose=3)
Starting gl.filter.callrate 
  Processing genlight object with SNP data
  Recalculating Call Rate
  Removing loci based on Call Rate, threshold = 0.95 
  Summary of filtered dataset
    Call Rate for loci > 0.95 
    Original No. of loci : 2932 
    Original No. of individuals: 70 
    No. of loci retained: 2402 
    No. of individuals retained: 70 
    No. of populations:  5 

Completed: gl.filter.callrate 
gl <- gl.filter.maf(gl, threshold = 3, verbose=3)
Starting gl.filter.maf 
  Processing genlight object with SNP data
  Removing loci with MAF < 0.0214285714285714 over all the dataset
                and recalculating FreqHoms and FreqHets
  Summary of filtered dataset
  MAF for loci > 0.02142857 
  Initial number of loci: 2402 
  Number of loci deleted: 1624 
  Final number of loci: 778 

Completed: gl.filter.maf 
system.time(yy <- gl.opt.ind.all(gl, ncores=4, first="optimal", plot = T))

   user  system elapsed 
   0.41    0.02    0.43 
write.csv(yy, file="mog.test2a.csv", row.names=F)