## ----setup, include = FALSE--------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 6, fig.height = 4.25 ) ## ----load--------------------------------------------------------------------- library(landgraph) ## ----graph-------------------------------------------------------------------- coords <- as.matrix(expand.grid(x = 0:2, y = 0:1)) # 6 demes on a 3 x 2 grid rownames(coords) <- paste0("deme", seq_len(nrow(coords))) coords g <- deme_graph(coords, neighbours = "lattice") g ## ----graph-parts-------------------------------------------------------------- str(g) g$edge_pairs ## ----graph-plot, fig.alt = "Six demes on a grid joined by rook-adjacency edges."---- op <- par(no.readonly = TRUE) par(mar = c(4, 4, 1, 1)) plot(g$vertex_coordinates, type = "n", asp = 1, xlab = "x", ylab = "y") ep <- g$edge_pairs segments(g$vertex_coordinates[ep[, 1], 1], g$vertex_coordinates[ep[, 1], 2], g$vertex_coordinates[ep[, 2], 1], g$vertex_coordinates[ep[, 2], 2], col = "grey60") points(g$vertex_coordinates, pch = 21, bg = "steelblue", cex = 3) text(g$vertex_coordinates, labels = seq_len(nrow(coords)), col = "white") par(op) ## ----graph-knn---------------------------------------------------------------- g_knn <- deme_graph(coords, neighbours = "knn", k = 2) nrow(g_knn$edge_pairs) # edge count under 2-nearest-neighbour adjacency ## ----snp-data----------------------------------------------------------------- set.seed(42) n_demes <- nrow(coords) n_snp <- 8 freqs <- runif(n_snp, 0.1, 0.9) # a true frequency per SNP Y <- vapply(freqs, function(p) rbinom(n_demes, size = 40, prob = p), numeric(n_demes)) rownames(Y) <- rownames(coords) colnames(Y) <- paste0("snp", seq_len(n_snp)) Y ## ----snp-cov------------------------------------------------------------------ S <- cov_from_biallelic(Y, N = 40) round(S, 3) ## ----fst---------------------------------------------------------------------- Nmat <- matrix(40, n_demes, n_snp) fst <- fst_from_biallelic(Y, Nmat) round(fst, 4) ## ----multi-features----------------------------------------------------------- x <- matrix(c(0, 1, 1, 1, 2, 0, 2, 1, 0, 2, 1, 2), ncol = 2, byrow = TRUE) groups <- rep(c("pop1", "pop2", "pop3"), each = 2) Sg <- cov_from_genetic_data(x, groups = groups) round(Sg, 3) ## ----multi-attrs-------------------------------------------------------------- attr(Sg, "level") # "population" once groups have replication attr(Sg, "diagonal") # the diagonal rule actually applied attr(Sg, "within_variance") # the within-population variances on the diagonal attr(Sg, "unit_size") # number of individuals per population ## ----multi-msat--------------------------------------------------------------- alleles <- data.frame( loc1_a = c(100, 100, 102, 102, 104, 104), loc1_b = c(100, 102, 102, 104, 104, 100), loc2_a = c(200, 202, 200, 202, 204, 204), loc2_b = c(202, 202, 204, 204, 204, 200) ) Sm <- cov_from_genetic_data( alleles, groups = groups, input = "allele_calls", loci = c("loc1", "loc1", "loc2", "loc2") ) round(Sm, 3) ## ----dist--------------------------------------------------------------------- D <- dist_from_cov(S) round(D, 3) ## ----dist-wrap---------------------------------------------------------------- D2 <- dist_from_biallelic(Y, N = 40) all.equal(D, D2) # same as the two-step route above ## ----grad--------------------------------------------------------------------- elevation <- coords[, "x"] + coords[, "y"] # one value per deme elevation eg <- edge_gradient(elevation, g) str(eg) ## ----flow--------------------------------------------------------------------- cen <- colMeans(g$vertex_coordinates) rotational <- function(xy) cbind(-(xy[, 2] - cen[2]), xy[, 1] - cen[1]) circ <- edge_flow(rotational, g) round(circ, 3) ## ----flow-plot, fig.alt = "A counter-clockwise vector field drawn as arrows at each deme over the graph edges."---- op <- par(no.readonly = TRUE) par(mar = c(4, 4, 1, 1)) vc <- g$vertex_coordinates fld <- rotational(vc) plot(vc, type = "n", asp = 1, xlab = "x", ylab = "y", xlim = range(vc[, 1]) + c(-0.4, 0.4), ylim = range(vc[, 2]) + c(-0.4, 0.4)) segments(vc[ep[, 1], 1], vc[ep[, 1], 2], vc[ep[, 2], 1], vc[ep[, 2], 2], col = "grey80") arrows(vc[, 1], vc[, 2], vc[, 1] + 0.3 * fld[, 1], vc[, 2] + 0.3 * fld[, 2], length = 0.08, col = "firebrick") points(vc, pch = 21, bg = "steelblue", cex = 2.5) par(op) ## ----quick-ref, eval = FALSE-------------------------------------------------- # library(landgraph) # # # 1. Build the spatial graph from deme coordinates # g <- deme_graph(coords, neighbours = "lattice") # or "knn" / "delaunay" # # # 2. Genetic covariance and distance from biallelic (SNP) counts # S <- cov_from_biallelic(Y, N = 40) # deme covariance # D <- dist_from_cov(S) # squared genetic distance # D <- dist_from_biallelic(Y, N = 40) # the two steps in one call # fst <- fst_from_biallelic(Y, Nmat) # pairwise F_ST (N as a matrix) # # # 2b. Covariance from microsatellite / multivariate data # Sg <- cov_from_genetic_data(x, groups = groups) # population covariance # Sg <- cov_from_genetic_data(alleles, groups = groups, # input = "allele_calls", # loci = c("loc1", "loc1", "loc2", "loc2")) # # # 3. Directional edge covariates for directed models # eg <- edge_gradient(elevation, g) # downhill drop; eg$d per directed edge # circ <- edge_flow(rotational, g) # circulation per undirected edge # # # 4. Hand off downstream # # terradish::wishart_covariance(S = S, ...) # symmetric resistance # # dragonflow::dragon(..., circulation = circ) # asymmetric gene flow