← All software

Tutorial · Landscape genetics in R

Migration corridors and climate change forecasts for the Yosemite toad

A hands-on walk through the analysis in Maier et al. (2022, Heredity), from pairwise FST to least cost corridors, Cubist models of connectivity, and maps of where migration is projected to shift by the end of the century.

The paper · Dryad data · Code · Data bundle

Why model corridors this way?

The Yosemite toad (Anaxyrus canorus) is a meadow specialist of the high Sierra Nevada. Tadpoles live in ultra-shallow snowmelt pools, so the species depends on snowpack, runoff and spring recharge, which are exactly the things climate change is expected to alter most. Adults forage and disperse through the forest, rock and shrub between meadows. A useful model of connectivity has to treat both: the environment along migration routes, and the contrast between the meadows at either end.

Map of Yosemite National Park with the 90 sampled Yosemite toad meadows colored by lineage, beside a dated phylogeny of the seven lineages
Study area and lineages, adapted from Maier and Vandergast (2024). (a) Yosemite National Park holds about a third of sites known to be occupied by Yosemite toads. Small green polygons are all meadows in the park, small black circles are known Yosemite toad meadows recorded since 1915, and large circles are the 90 meadows sampled here, colored by lineage. Random jitter protects the locations of this threatened species. The inset shows the range of the species in grey. (b) The lineages and their estimated divergence dates (Maier et al. 2019): four pure lineages and three fused or admixed ones (asterisks).

Most landscape genetic studies fold every hypothesis into a single resistance surface. That works for one or two variables, but it gets unwieldy fast, and translating raw values into resistance is somewhat subjective. In the paper we split the problem in two. First we find the most likely migration paths using two features already known to matter, slope and vegetation moisture. Then we pull raw values of dozens of features out of corridors around those paths and let a machine learning model sort out which ones explain genetic differentiation. Because the second step works on raw features, each group of features can even have its own corridor width.

1. Genetic distancesPairwise FST from RADseq SNPs, and the net direction of migration (δM).2. Migration pathsEleven slope and vegetation resistance blends, ranked with mixed models.3. CorridorsLeast cost paths with buffers, and least cost corridors at four thresholds.4. BandwidthsRandom forests pick the corridor width for each feature group.5. Cubist modelsPCA within groups, Cubist regression of FST and δM, VIF filtering.6. ForecastsFuture climate pushed through the models and mapped across every corridor.

Each step below shows the main pieces of code. The complete scripts are in the code download, and they reproduce the published tables. Where a step takes hours on a full dataset, the tutorial shows the code and then reads the saved result, so you can follow along on a laptop.

Data and setup

You need two downloads. The raw inputs (Stacks FST tables, resistance surfaces, environmental rasters, lineage assignments) are on Dryad at doi:10.5061/dryad.xsj3tx99h. Unzip Corridors.zip, FST_YOSE.zip and ResistanceGA.zip into one folder. The tutorial data bundle adds the pairwise tables that steps 2 and 3 produce: path lengths under every hypothesis, environmental values for every corridor bandwidth, and the at-site contrasts. Unzip it into the same folder. The raw reads are on the NCBI SRA under BioProject PRJNA558546.

About locations. The Yosemite toad is federally threatened, so the archive leaves out meadow coordinates. Step 1, the path ranking in step 2, and steps 4 and 5 run from the downloads alone. Building paths and corridors (steps 2 and 3) and mapping the forecasts (step 6) need meadow locations, which qualified researchers can request from the corresponding author. You can also point the same code at your own sites. Every map on this page shows the park as a whole, with meadow symbols displaced by up to 1 km, as in the paper.

The code uses current packages, with sf and terra in place of the retired rgdal, rgeos and maptools. It was tested on R 4.5.3.

install.packages(c("dplyr", "tidyr", "sf", "terra", "gdistance", "exactextractr",
                   "lme4", "MuMIn", "caret", "ranger", "Cubist", "spatialRF",
                   "igraph", "ggplot2", "patchwork", "ggnewscale", "scico", "doParallel"))
DATA_DIR  <- "path/to/unzipped/dryad"          # holds Corridors/, FST_YOSE/, ResistanceGA/
CORR_DIR  <- file.path(DATA_DIR, "Corridors")
MODEL_DIR <- file.path(CORR_DIR, "models2", "SlopeVeg_90_10_")

Step 1. Genetic differentiation and the direction of migration

The genetic data are ddRADseq haplotypes for 535 tadpoles from 90 meadows (2,318 polymorphic loci), processed in Stacks. For every pair of meadows, Stacks wrote a table with one row per SNP. Pairwise FST is the sample-size weighted variance in allele frequency between the two meadows, averaged over SNPs. SNPs whose frequencies do not differ (Fisher’s exact test, P ≥ 0.05) count as zero.

snp_fst <- function(file) {
  d <- read.delim(file, check.names = FALSE)
  p <- cbind(d$p_1_freq, d$p_2_freq)            # allele frequency in each meadow
  n <- cbind(d$n_1, d$n_2)                      # sample sizes
  pbar <- rowSums(p * n) / rowSums(n)
  w <- 2 * n / rowSums(n)
  fst <- rowSums(w * (p - pbar)^2) / (2 * pbar * (1 - pbar))
  fst[d$`Fisher's P` >= 0.05] <- 0
  mean(fst)
}
files <- list.files(file.path(DATA_DIR, "FST_YOSE", "Combined", "fst"),
                    pattern = "^batch_1\\.fst_M[0-9]+-M[0-9]+\\.tsv$", full.names = TRUE)
fst <- parallel::mclapply(files, snp_fst, mc.cores = 8)

Run over all 4,005 pairs, this matches the archived Fst.txt to within 5 × 10-10, which is just rounding.

Differentiation alone has no direction. To capture asymmetry we use directional GST (Sundqvist et al. 2016), which compares each meadow with a hypothetical gene pool shared by the pair. The difference between emigration and immigration gives a relative term, δM. Positive values mean a meadow sends out more migrants than it receives. Working with the difference avoids estimating any explicit migration rate and leans less on island model assumptions such as drift–migration equilibrium. The estimates come from our earlier study of gene pool boundaries (Maier et al. 2022, Frontiers in Conservation Science) and are stored in Fst.txt as gst_out and gst_in.

gen <- read.delim(file.path(CORR_DIR, "fst", "Fst.txt")) |>
  transmute(a = pmin(pop1, pop2), b = pmax(pop1, pop2),   # smaller meadow ID first
            fst = fst_wc.mean, dM = gst_out - gst_in) |>
  rename(pop1 = a, pop2 = b)
Heat maps of pairwise FST and directional migration among 90 Yosemite toad meadows, ordered by lineage
Pairwise FST and δM among the 90 meadows, ordered by lineage. Differentiation is low within lineages and high between the isolated western and northern groups and everything else. δM is read from row to column: red cells mark meadows that send more migrants than they receive.

Step 2. Choosing the most likely migration paths

Topographic complexity and moisture are already known to shape Yosemite toad connectivity, so we built path hypotheses from those two features. ResistanceGA (Peterman 2018) optimized a resistance transformation for each one at 300 m, using a genetic algorithm to maximize the fit of mixed models between FST and resistance distance. Both came out as inverse-reverse monomolecular curves. Slope resistance rises gently, so a 30° slope still costs under 2,000, but there is a sharp inflection near 70°. That matches what we see in the field: toads climb moderately steep drainages but seldom breed in meadows cut off by very steep terrain. Steep ridgetops were scored as impassable.

# ResistanceGA (not run here; it takes days). See ResistanceGA/ResistanceGA.R on Dryad.
GA.inputs <- GA.prep(ASCII.dir = "Resistance/", Results.dir = "Results/", select.trans = "M",
                     max.cont = 1e6, cont.shape = "increase", seed = 12345, maxiter = 50, run = 10)
gdist.inputs <- gdist.prep(n.Pops = 90, samples = meadow_points, response = fst_vector,
                           method = "costDistance", directions = 8,
                           transitionFunction = function(x) 1 / mean(x))
result <- SS_optim(gdist.inputs = gdist.inputs, GA.inputs = GA.inputs)

The optimized slope and vegetation surfaces were rescaled, blended in proportions from 0:100 to 100:0, and saved at 30 m in Corridors/resistance2/30m. That gives eleven path hypotheses, plus straight-line distance as the null.

Resistance surfaces for slope, vegetation and the combined 90 percent slope model across Yosemite National Park
Slope alone, vegetation moisture alone, and the 90:10 blend that best explained FST. Ridgelines treated as barriers are near black. The white line is the park boundary.

For each blend, gdistance builds a transition layer. Barrier cells are set to NA so no path can cross them, and conductance between neighboring cells is the inverse of their mean resistance. Path length is measured over the terrain surface, not on the flat map.

library(gdistance)
r <- raster::raster(file.path(CORR_DIR, "resistance2", "30m", "SlopeVeg_90_10_30m.tif"))
r[r >= 1e6] <- NA                                    # ridgelines
tr <- transition(r, function(x) 1 / mean(x), directions = 8)
tr <- geoCorrection(tr, type = "c")                  # about a minute for the whole park
path <- shortestPath(tr, xy["359", ], xy["1543", ], output = "SpatialLines") |>
  sf::st_as_sf()
surface_length <- function(line, dem) {              # 3D length along the DEM
  co <- sf::st_coordinates(line)[, 1:2]
  z  <- terra::extract(dem, co)[, 1]
  sum(sqrt(diff(co[, 1])^2 + diff(co[, 2])^2 + diff(z)^2))
}

As a check, the path between meadows 359 and 1543 rebuilt this way is 27,257.2 m long, the same as the archived value. The archive holds path lengths for every pair under every blend, so ranking the hypotheses is quick. We kept pairs whose shortest path is under 30 km, since earlier work found no isolation by distance beyond that scale. For each blend we fit a mixed model of FST on path length, with source and destination meadow as random effects.

library(lme4); library(MuMIn)
fit_one <- function(m) {
  fit <- lmer(as.formula(paste0("fst ~ ", m, " + (1 | From) + (1 | To)")), data = dd)
  r2  <- r.squaredGLMM(fit)
  tibble(Model = m, R2m = r2[, "R2m"], R2c = r2[, "R2c"], AIC = AIC(fit),
         AICc = AICc(fit), BIC = BIC(fit), LL = as.numeric(logLik(fit)))
}
rank_tab <- bind_rows(lapply(models, fit_one)) |> arrange(desc(LL))
Table 3. Ranking of migration path hypotheses (mixed models of FST on path length)
SlopeVegetationR²mR²cAICAICcBIClog L
0.90.10.1040.912−6,176.878−6,176.823−6,151.9043,093.439
0.80.20.1020.911−6,163.112−6,163.056−6,138.1373,086.556
0.40.60.1000.912−6,159.875−6,159.820−6,134.9013,084.938
0.50.50.0980.911−6,152.689−6,152.634−6,127.7153,081.345
100.0900.910−6,143.724−6,143.668−6,118.7493,076.862
0.70.30.0970.910−6,143.199−6,143.144−6,118.2253,076.600
0.60.40.0960.910−6,139.191−6,139.136−6,114.2173,074.596
0.30.70.0940.910−6,138.701−6,138.646−6,113.7273,074.350
0.20.80.0930.910−6,135.075−6,135.020−6,110.1013,072.538
010.1030.908−6,126.692−6,126.637−6,101.7183,068.346
0.10.90.0960.905−6,119.832−6,119.777−6,094.8583,064.916
NoneNone0.0860.904−6,101.830−6,101.775−6,076.8563,055.915

The 90% slope, 10% vegetation model ranks first on log likelihood, AIC and marginal R², and the runner-up also leans on slope (80%). Every path model beats straight-line distance. Because ridgelines bisect the park, this model finds only one route linking each low-elevation lineage (Y-South, Y-West) to the high-elevation Y-East lineage.

Map of least cost paths between Yosemite toad meadows colored by FST, with meadows colored by lineage
The chosen path network. Least cost paths under 30 km, colored by FST (pale for similar, dark for differentiated). Meadows are colored by lineage and displaced by up to 1 km.

Step 3. From a single path to a corridor

A toad does not walk a one-pixel line, and there are usually several routes of similar cost. So rather than extract environment along the least cost path alone, we tried six corridor bandwidths around it. Two are simple buffers of 100 m and 500 m, chosen around the mean yearly dispersal distance of about 275 m. The other four are least cost corridors. For a pair of meadows, we sum the accumulated cost surfaces from each one; cells with low totals lie on cheap routes between them. We keep the cheapest 0.1%, 0.5%, 1% or 5% of cells and rescale them so the best route has a weight of 1 and the corridor edge a weight of 0. Those weights then decide how much each cell’s environment counts.

acc_cost <- function(id) {
  a <- terra::rast(accCost(tr, xy[as.character(id), , drop = FALSE]))
  a[is.infinite(a)] <- NA
  a
}
lcc <- function(acc_i, acc_j, q) {
  s <- acc_i + acc_j
  rng <- minmax(s)
  s <- (s - rng[1]) / (rng[2] - rng[1])
  v <- sort(values(s, na.rm = TRUE))
  s[s > v[round(length(v) * q)]] <- NA         # keep the cheapest q share of cells
  1 - s / max(values(s), na.rm = TRUE)          # weight 1 on the best route, 0 at the edge
}
acc_i <- acc_cost(359); acc_j <- acc_cost(1543)
lccs <- rast(lapply(c(0.001, 0.005, 0.01, 0.05), \(q) lcc(acc_i, acc_j, q)))
buffers <- lapply(c(100, 500), \(w) sf::st_buffer(path, w))
Six corridor bandwidths for one pair of meadows: two least cost path buffers and four least cost corridors
Six candidate bandwidths for meadows 359 and 1543, as in Fig. 2 of the paper. The white or dashed line is the least cost path. The broadest corridor (LCC 0.05) takes in many routes of similar cost, plus peripheral habitat that toads might use now and then. It matches the archived corridor to within 3 × 10-7.

Next, environmental features are summarized inside each corridor. The archive includes 18 climate layers from the California Basin Characterization Model (present and 2070–2099 under CCSM4 RCP 8.5), LANDSAT soil moisture, MODIS snowmelt timing, soil age, topography, vegetation, fire frequency, and trail and road crossings weighted by use. For buffers we take an exact, coverage-weighted mean with exactextractr. For corridors we resample each layer to the 30 m corridor grid and weight every cell by its corridor weight.

corridor_mean <- function(env, w) {
  env <- resample(env, w, method = "bilinear")
  global(env * w, "sum", na.rm = TRUE)[[1]] / global(w, "sum", na.rm = TRUE)[[1]]
}
buffer_mean <- function(env, poly) {
  x <- exactextractr::exact_extract(env, poly, progress = FALSE)[[1]]
  x <- x[!is.na(x$value), ]
  sum(x$value * x$coverage_fraction) / sum(x$coverage_fraction)
}
snow <- rast(file.path(CORR_DIR, "environment", "climate", "aprpck1981_2010_ave.tif"))
corridor_mean(snow, lccs[[4]])

For this pair the corridor-weighted April 1 snowpack comes out at 603.4 mm (archived table: 603.4 mm), and mean elevation in the 100 m buffer at 2,495 m (archived: 2,494 m). The same features were also summarized inside each meadow polygon, and the difference between source and destination meadow became a set of at-site features. These sit alongside meadow network measures: degree, eigenvector centrality and clustering coefficient from igraph, meadow area, and breeding probability with and without network effects (Berlow et al. 2013). Looping over 1,024 pairs, six bandwidths and about sixty layers takes a while, so the remaining steps read the finished tables from the data bundle (Corridors/models2/SlopeVeg_90_10_/).

Step 4. Letting each feature group pick its own bandwidth

Climate might influence toads over a broad swath of landscape, while soil age might only matter right along the route. To allow for that, we trained a random forest of FST on each feature group under each bandwidth and kept the bandwidth with the lowest cross-validated RMSE. Each pair enters the training data twice, once in each direction. Pairs involving frequently sampled meadows are down-weighted so a handful of well-connected meadows do not dominate.

library(caret)
set.seed(12345)
folds <- createFolds(labs$fst, k = 5, returnTrain = TRUE)
ctrl  <- trainControl(method = "cv", number = 5, index = folds)
fit_group <- function(group, bw) {
  x <- bands[[bw]][, GROUPS[[group]], drop = FALSE]
  grid <- expand.grid(mtry = seq_len(ncol(x)), splitrule = "variance",
                      min.node.size = c(1, 5, 10))
  train(x = x, y = labs$fst, method = "ranger", metric = "RMSE", tuneGrid = grid,
        trControl = ctrl, weights = labs$Weight, num.trees = 5000)
}

With 5,000 trees and a full grid, the 48 group-by-bandwidth fits take a few hours, so here we read the saved ranking (models2/corridor_rank.txt, Table S4 in the paper).

Table 4. Best corridor bandwidth for each feature group (random forests, five-fold CV)
Feature groupBandwidthmtrymin.node.sizeRMSER²MAE
ClimateLCC 0.05850.0210.6740.016
FireLCC 0.051100.0310.2850.024
TrafficLCC 0.05110.0260.4900.020
GeologyLCP 100 m1100.0340.1370.027
MoistureLCC 0.05250.0220.6200.017
MeltoffLCC 0.05150.0240.5630.018
TopographyLCC 0.05750.0210.6640.016
VegetationLCC 0.05650.0210.6750.016

Every group except geology chose the broadest bandwidth, LCC 0.05. Geology preferred the 100 m buffer, though with a single variable that relationship was weak. In effect the broad corridors behave a bit like circuit theory, taking many plausible routes into account, but each feature still enters the model in its raw form.

Step 5. Cubist models of FST and δM

Tree ensembles handle many correlated features well, but collinear features distort their importance scores. So we first ran a PCA within each feature group (groups of three or more features, centered and scaled), which removes most of the redundancy among related layers. Two more predictors were added: path length (LCPdist) for isolation by distance, and a lineage effect (LineageCross), which is the time to the most recent common ancestor of the two lineages, or zero within a lineage.

group_pca <- function(x, prefix) {
  x <- x[, vapply(x, \(v) length(unique(v)) > 1, logical(1)), drop = FALSE]
  if (ncol(x) <= 2) return(list(x = x, pca = NULL))
  pca <- prcomp(x, scale. = TRUE)
  s <- as.data.frame(pca$x); names(s) <- paste0(prefix, "_", names(s))
  list(x = s, pca = pca)
}

Why Cubist? Random forests and xgboost extrapolate poorly when relationships are close to linear, and in early tests random forests badly underpredicted extreme values of δM. Cubist (Quinlan 1992, 1993) replaces the constant at each leaf of a rule-based tree with a linear model, so a different regression equation is fit to each partition of the data. Committees (boosted sets of trees) and neighbors (nearby training cases used to adjust predictions) are tuned with caret. The first model uses every feature. Its importance ranking then decides which feature to keep whenever two features from different groups are collinear (VIF > 10, using spatialRF::auto_vif), and the model is refit on what remains.

tune_cubist <- function(x, y) {
  set.seed(12345)
  folds <- createFolds(y, k = 10, returnTrain = TRUE)
  ctrl  <- trainControl(method = "cv", number = 10, index = folds, savePredictions = "final")
  grid  <- expand.grid(committees = c(1, 10, 50, 75, 100), neighbors = c(0, 1, 5, 7, 9))
  train(x = x, y = y, method = "cubist", metric = "RMSE", tuneGrid = grid, trControl = ctrl)
}
full <- tune_cubist(X, labs$dM)
imp  <- varImp(full$finalModel)
keep <- spatialRF::auto_vif(x = select(X, -LCPdist, -LineageCross), vif.threshold = 10,
                            preference.order = rownames(imp)[order(-imp$Overall)])
vars  <- c("LCPdist", "LineageCross", keep$selected.variables)
final <- tune_cubist(X[, vars], labs$dM)

Several components have almost no variance (the eight aspect proportions, for instance, always sum to one), and which member of a nearly collinear pair survives the VIF filter can hinge on rounding. A run with current package versions keeps 64 features for FST and 69 for δM (against 68 and 60 in the paper), mostly the same features as the paper but not all. The data bundle includes the feature lists of the published models (published_features.csv). Refitting on those gives back the published δM model exactly and the FST model to within 0.005 in any prediction, so the rest of this tutorial uses them.

pub   <- read.csv("published_features.csv")
final <- tune_cubist(X[, pub$feature[pub$model == "dM"]], labs$dM)

The published FST model uses 68 features and the δM model 60. Both do best with the maximum number of committees, and both fit well: ten-fold cross-validated R² is 0.88 for FST and 0.79 for δM (the paper reports 0.88 and 0.78).

Table 5. Final Cubist models (ten-fold CV)
ModelCommitteesNeighborsRMSER²MAE
FST10050.0130.8800.009
δM10050.0280.7880.021
Observed versus cross-validated predictions and residuals for Cubist models of FST and delta M
Model fit. Top: ten-fold cross-validated predictions against observed values, with a linear trend in purple. Bottom: residuals, which are roughly even across the range of predictions.

The two models emphasize different things. FST mostly reflects how connected two meadows are overall, and it leans on a few between-site features. δM reflects contrasts that favor movement in one direction, and many at-site features share the importance. Snowpack-related climate (meltoff timing variability, runoff, recharge) ranks high in both. For δM, contrasts in meadow area, number of neighboring meadows and breeding probability stand out, which echoes the hub and satellite structure we found within meadow neighborhoods.

Variable importance for the final Cubist models of FST and delta M, colored by feature group
Variable importance in the final models (top 30 features each), scaled to a maximum of 100. Principal components are labeled with the two original features that load most strongly on them. Faded bars are at-site features, the difference between source and destination meadow.

Step 6. Forecasting connectivity under climate change

To forecast, we swap present climate for the 2070–2099 projections (CCSM4, RCP 8.5, a business-as-usual scenario) and project them onto the present-day PCA loadings, so the components keep their meaning. Every other feature stays as it is. The models then predict FST and δM for each directed pair, now and in the future.

fut <- setNames(clim_table[, paste0(GROUPS$CLIMATE, "_f")], GROUPS$CLIMATE)
Xf  <- X
Xf[, colnames(pca_climate$x)] <- predict(pca_climate, fut)   # same loadings as today
# (at-site climate is projected the same way)
now    <- predict(final$finalModel, X[, vars])
future <- predict(final$finalModel, Xf[, vars])
change <- future - now

To put these pairwise forecasts on a map, each pair’s value is spread over its LCC 0.05 corridor, scaled by the corridor weight so less likely routes count for less, and overlapping corridors are averaged cell by cell. For δM we also keep track of direction. Each pair contributes a vector from source to destination, reversed if δM is projected to drop, and the vectors are summed in every cell to give a net direction of change.

for (r in rows_of_this_pair) {
  s  <- sign(dm$change[r])
  dx <- xy[to, 1] - xy[from, 1]; dy <- xy[to, 2] - xy[from, 2]
  mag[on] <- mag[on] + w * abs(dm$change[r]); n[on] <- n[on] + 1
  vx[on]  <- vx[on] + w * dx * s;            vy[on] <- vy[on] + w * dy * s
}
# mean magnitude = mag / n; net bearing = atan2(vx, vy)

Finally, we treat the meadows as a network. Edges are weighted by how connected each pair is predicted to be (the maximum FST minus the predicted value), and eigenvector centrality shows how central each meadow is to park-wide gene flow, now and in the future.

library(igraph)
m[cbind(from, to)] <- max(c(fst_now, fst_future)) - fst_now
g <- graph_from_adjacency_matrix(m, mode = "max", weighted = TRUE)
centrality_now <- eigen_centrality(g)$vector
Map of present-day connectivity among Yosemite toad meadowsMap of projected change in FST and network centrality by 2070 to 2099

Connectivity now and in the future. Left: present-day connectivity, averaged over every corridor that covers a cell. Right: projected change in FST by 2070–2099, with meadows that become more central (circles) or less central (triangles) to the network.

Map of projected asymmetrical migration shift with arrows showing net direction
Projected shift in migration asymmetry (δM), 2070–2099. Color shows the average magnitude of change in each cell. Arrows show the net direction on a 3 km grid, with longer arrows where change is larger.

The connectivity surface shows regional corridors of high flow and pinch points where ridgelines, fire-prone low country or sparse meadow habitat cut across. The Y-North lineage, broken up by canyons, is poorly connected compared with the rest. Looking ahead, the biggest losses in connectivity fall on Y-West, Y-South and admixed areas in the south. Centrality moves from the south and west toward the north and east.

The δM forecast points the same way. Net movement runs from west to east, toward higher ground. Given the pinch points in the southern corridors, movement out of Y-South would go up the Middle Fork of the Merced River (north of the Clark Range) or up the South Fork straight into the Clark Range. Y-West has a single likely route up Tenaya Creek into the Tuolumne watershed. Smaller vectors inside Y-East and Y-North suggest some movement north as well. Taken together, the models predict a range shift toward higher elevation and latitude by 2100. These maps could help guide where to protect, or even assist, migration as lower meadows dry out.

Using this workflow for your own species

Nothing here is specific to toads. The approach suits any patch-limited species where you have pairwise genetic distances between discrete sites and a sense of what limits movement. A few things to keep in mind:

  • The first model matters. Corridors come from a simple resistance model, so if that model is uninformed, the corridors will carry irrelevant landscape. Build it from features the literature already supports.
  • Pre-modeling partials out some importance. Since paths were chosen on slope, topography ranks lower in the later models than it might otherwise. Read importance scores with that in mind.
  • Direction is not in the importance scores. Tree ensembles say which features matter, not whether they raise or lower connectivity. Partial dependence plots help with that.
  • Keep phylogeography in the model. Deep lineage splits add FST that has nothing to do with the current landscape. A lineage term soaks that up.
  • Plan for scale. Accumulated cost surfaces and corridor rasters for a thousand pairs take time and disk space. Write them to disk once and run the extraction in parallel.

How to cite

  • Maier PA, Vandergast AG, Ostoja SM, Aguilar A, Bohonak AJ (2022) Landscape genetics of a sub-alpine toad: climate change predicted to induce upward range shifts via asymmetrical migration corridors. Heredity 129:257–272. doi:10.1038/s41437-022-00561-x. Data: doi:10.5061/dryad.xsj3tx99h

Related work

  • Maier PA, Vandergast AG, Ostoja SM, Aguilar A, Bohonak AJ (2022) Gene pool boundaries for the Yosemite toad (Anaxyrus canorus) reveal asymmetrical migration within meadow neighborhoods. Frontiers in Conservation Science 3:851676. doi:10.3389/fcosc.2022.851676
  • Maier PA, Vandergast AG (2024) Yosemite toad (Anaxyrus canorus) transcriptome reveals interplay between speciation genes and adaptive introgression. Molecular Ecology 33:e17317. doi:10.1111/mec.17317
  • Maier PA, Vandergast AG, Ostoja SM, Aguilar A, Bohonak AJ (2019) Pleistocene glacial cycles drove lineage diversification and fusion in the Yosemite toad (Anaxyrus canorus). Evolution 73:2476–2496. doi:10.1111/evo.13868
  • Peterman WE (2018) ResistanceGA: an R package for the optimization of resistance surfaces using genetic algorithms. Methods in Ecology and Evolution 9:1638–1647.
  • Sundqvist L, Keenan K, Zackrisson M, Prodöhl P, Kleinhans D (2016) Directional genetic differentiation and relative migration. Ecology and Evolution 6:3461–3475.
  • van Etten J (2017) R package gdistance: distances and routes on geographical grids. Journal of Statistical Software 76:1–21.
  • Quinlan JR (1993) Combining instance-based and model-based learning. Proceedings of the Tenth International Conference on Machine Learning, 236–243.
  • Berlow EL, Knapp RA, Ostoja SM et al. (2013) A network extension of species occupancy models in a patchy environment applied to the Yosemite toad (Anaxyrus canorus). PLoS ONE 8:e72200.