Genetic variation in the Scandinavian Arctic fox

 

Christopher Alan Cockerill 11th March 2026

Exercise: genetic processes in small populations

Conservation of Populations BL7076, Stockholm University

Data adapted from Cockeril et al (2022)

 

 

Aims

 

 

The population

Figure 1. Map showing the distribution of Arctic tundra habitat (Scandinavia: alpine tundra [60]; Kola: oro-arctic tundra [61]) in relation to study sample areas in Northern Sweden (Vindelfjällen-Arjeplog), southern Sweden (Helags), northern Norway (Saltfjellet, Øvre Dividal, Reisa nord, the Varanger Peninsula), western Russia (Kola Peninsula and Yamal), Mid-Russia (Taymyr) and eastern Russia (Indigirka, Faddeyesky Island and Wrangel Island.
Figure 1. Map showing the distribution of Arctic tundra habitat (Scandinavia: alpine tundra [60]; Kola: oro-arctic tundra [61]) in relation to study sample areas in Northern Sweden (Vindelfjällen-Arjeplog), southern Sweden (Helags), northern Norway (Saltfjellet, Øvre Dividal, Reisa nord, the Varanger Peninsula), western Russia (Kola Peninsula and Yamal), Mid-Russia (Taymyr) and eastern Russia (Indigirka, Faddeyesky Island and Wrangel Island.

 

 

 

 

Installation

We need to install some packages to complete the exercise, take some time to make sure you have them loaded and that they are working.

# STEP 1: Install regular packages one by one
# Just copy and paste each line, one at a time
install.packages("vcfR")
install.packages("tidyverse")  
install.packages("RColorBrewer")
install.packages("ggrepel")
install.packages("readxl")

# STEP 2: Install BiocManager (special installer)
install.packages("BiocManager")

# Load BiocManager
library(BiocManager)

# STEP 3: Install genetics packages using BiocManager
BiocManager::install("dartR")
BiocManager::install("adegenet")

 

 

Load the packages

# Load libraries
library(vcfR)
library(tidyverse)
library(RColorBrewer)
library(ggrepel); 
library(readxl)
library(dartR)
library(adegenet)

 

 

Data import

Now we will import the data in vcf format and the accompanying metadata, see Figure 1 for how a vcf file is formatted below.

Figure 1. The structure of a VCF file, note the header includes descriptive information about the contents, and the body includes the chromosome, position and genotype information (from Dave Tang, https://davetang.github.io/learning_vcf_file/)
Figure 1. The structure of a VCF file, note the header includes descriptive information about the contents, and the body includes the chromosome, position and genotype information (from Dave Tang, https://davetang.github.io/learning_vcf_file/)

 

 

# STEP 1: Set your folder
# CHANGE THIS to your folder path!
setwd("/home/christopheralancockerill/Documents/Work/PhD_work/Teaching/Conservation of Populations/") # YOUR folder path

# STEP 2: Read your genetic data
vcf <- read.vcfR("popgen_practical_scaff22.biallelic.0missing_subset.vcf")

# STEP 3: Convert to genlight format
gl_data <- vcfR2genlight(vcf)

# STEP 4: Add population info
metadata <- read_excel("popgen_metadata.xlsx")
pop(gl_data) <- metadata$pop
ploidy(gl_data) <- 2
Here you can see that we have 83 indidvuals genotyped for 12,116 SNPs and there is zero missing data.
Here you can see that we have 83 indidvuals genotyped for 12,116 SNPs and there is zero missing data.

 

 

#check the file
vcf.gl
This shows that the file has been converted correctly and still contains the same number of SNPs and individuals. Genlight objects store genotypes of binary SNPs in a compact way, with genotypes encoded as 0: homozygous for reference allele, 1: heterozygous, 2: Homozygous for alternate allele.
This shows that the file has been converted correctly and still contains the same number of SNPs and individuals. Genlight objects store genotypes of binary SNPs in a compact way, with genotypes encoded as 0: homozygous for reference allele, 1: heterozygous, 2: Homozygous for alternate allele.

 

 

Now we will plot the data using ggplot and look to see if there is any populations structure.

# STEP 1: Run PCA (takes 2-3 minutes)
pca_result <- glPca(gl_data, nf = 5)

# STEP 2: Create a simple data frame for plotting
pca_data <- data.frame(PC1 = pca_result$scores[,1], 
                       PC2 = pca_result$scores[,2],
                       Population = pop(gl_data))

# STEP 3: Calculate variance explained
var_exp <- round(pca_result$eig[1:2]/sum(pca_result$eig)*100, 1)

# STEP 4: Create the plot (this is the main result!)
ggplot(pca_data, aes(x = PC1, y = PC2, color = Population)) +
  geom_point(size = 3) +
  labs(x = paste0("PC1 (", var_exp[1], "%)"),
       y = paste0("PC2 (", var_exp[2], "%)")) +
  theme_bw() + scale_color_brewer(palette = "Set1")


# STEP 5: Save your plot
ggsave("my_pca_plot.pdf", width = 8, height = 6)
Figure 2. PC1 and PC2, We can see that patterns are starting to emerge regarding the genetic relatedness within and between the populations. However, it may be difficult to see some of the subtle features of the diversity that may be important. Lets explore the data in a slightly different way.
Figure 2. PC1 and PC2, We can see that patterns are starting to emerge regarding the genetic relatedness within and between the populations. However, it may be difficult to see some of the subtle features of the diversity that may be important. Lets explore the data in a slightly different way.

 

Questions

  1. How does the PCA plot reveal patterns of genetic differentiation between the Scandinavian and Russian populations of arctic foxes?
  2. What do the first few principal components represent in terms of genetic variation among individuals? How might historical demographic events influence these patterns?
  3. Which subpopulations are most genetically differentiated and what contemporary processes might be driving this isolation?

 

 

Task 2 - Genetic variation

Now we are going to calculate some traditional populations genetics estimates from our data. You are probably familiar with Hardy-Weinberg equilibrium.

Briefly, Hardy-Weinberg equilibrium (HWE) is a fundamental principle in population genetics that describes the expected genotype frequencies in a population under certain conditions. It serves as a null hypothesis against which observed genotype frequencies can be compared to assess departures from expected values, which may indicate evolutionary processes such as genetic drift, migration, mutation, or natural selection.

Remember the principles?

  1. Random Mating: Individuals in the population mate randomly with respect to their genotypes.
  2. No Migration: There is no migration into or out of the population.
  3. No Mutation: There is no new mutation introducing new alleles into the population.
  4. No Selection: There is no differential survival or reproductive advantage associated with particular genotypes.
  5. Large Population Size: The population size is large enough to prevent random sampling errors from significantly affecting genotype frequencies.
#Now we will explore genetic variation within the populations with the package DartR


# STEP 1: Clean up data (remove monomorphic loci)
gl_clean <- gl.filter.monomorphs(gl_data)
gl_clean <- gl.recalc.metrics(gl_clean) # Calculate required metrics
gl_clean@other$loc.metrics <- as.data.frame(gl_clean@other$loc.metrics) # Fix format

# STEP 2: Calculate heterozygosity
gl.report.heterozygosity(gl_clean, method = 'pop')
Figure 3. Take look at the plot, it contains barplots for observed heterozygosity, adjusted heterozygosity, and inbreeding coefficients (FIS). Can you see any noticeable differences, what kind of evolutionary processes do you think are at play within each subpopulation?
Figure 3. Take look at the plot, it contains barplots for observed heterozygosity, adjusted heterozygosity, and inbreeding coefficients (FIS). Can you see any noticeable differences, what kind of evolutionary processes do you think are at play within each subpopulation?

 

 

Figure 4. The output report heterozygosity by population.
Figure 4. The output report heterozygosity by population.

 

 

Now lastly, It seems that these populations of arctic foxes vary in genetic variation and show substantial populations structure. Lets take a quick look at pairwise fst values to see if we can find anything interesting.

#Now lets take a look at the genetic distance of the populations by calculating Fst
#this might take a few minutes.

# STEP 3: Calculate Fst (genetic distance between populations)
gl.fst.pop(gl_clean)
Figure 5. The output from fst analysis, how do you interpet this, would you expect these values if there was frequent gene flow between these populations?
Figure 5. The output from fst analysis, how do you interpet this, would you expect these values if there was frequent gene flow between these populations?

 

Questions

  1. Describe the patterns of observed and expected heterozygosity and inbeeding coefficients within each population. What do these measures tell us about the genetic diversity and inbreeding levels?
  2. How would you explain the reduced heterozygosity in the Scandinavian samples, what micro-evolutionary processes may be involved?
  3. How does the FIS value reflect the degree of inbreeding within each population? What implications might high FIS values have for the long-term viability of populations?
  4. The inbreeding coefficient appears to be quite high in western Russia, can you explain why this pattern may emerge, what could be causing greater inbreeding in this region?
  5. How do the pairwise FST values between populations reflect the degree of genetic differentiation? What factors could contribute to the observed values?

 

 

Summary

In this exercise, we have shown you how to:

  • Perform genetic data exploration and population genetics in R using whole-genome NGS data from Arctic fox populations in Scandinavia and Russia to understand the genetic relatedness within and between populations, and the processes that shapes genetic structure.
  • Explored genetic diversity, population structure, and differentiation using PCA plots, heterozygosity analysis, and pairwise FST values.

 

Assignment questions

  1. Discuss the conservation implications of low genetic variation in the Scandinavian population compared to the Russian population. How might reduced genetic diversity affect the ability of the Scandinavian population to adapt to environmental changes or disease outbreaks?
  2. How can information derived from genetic analyses, such as PCA and FST values, inform conservation strategies for arctic fox populations? What management actions could be implemented to mitigate the effects of low genetic diversity?
  3. Suggest potential future research directions based on the findings from this exercise. How could additional genetic data, such as whole-genome sequencing or population genomic analyses, further elucidate the evolutionary dynamics and conservation needs of arctic fox populations?
  4. Consider the broader context of conservation genetics and the applicability of similar analyses to other endangered or threatened species. How can insights gained from studying arctic fox populations inform conservation efforts for other species facing similar challenges?