Relationship matrices are fundamental tools in quantitative genetics
and animal breeding. They quantify the genetic similarity between
individuals due to shared ancestry, which is essential for estimating
breeding values (BLUP) and managing genetic diversity. The
visPedigree package provides efficient tools for
calculating various relationship matrices and visualizing them through
heatmaps and histograms.
pedmat()The pedmat() function is the primary tool for
calculating relationship matrices. It supports both additive and
dominance relationship matrices, as well as their inverses.
The method parameter in pedmat() determines
the type of matrix to calculate:
tidyped(..., inbreed = TRUE)).Most calculations require a pedigree tidied by
tidyped().
# Load example pedigree and tidy it
data(small_ped)
tped <- tidyped(small_ped)
# Calculate Additive Relationship Matrix (A)
mat_A <- pedmat(tped, method = "A")
# Calculate Dominance Relationship Matrix (D)
mat_D <- pedmat(tped, method = "D")
# Calculate inbreeding coefficients (f)
vec_f <- pedmat(tped, method = "f")By default, pedmat() returns a sparse matrix (class
dsCMatrix from the Matrix package) for
relationship matrices. This is highly memory-efficient for large
pedigrees where many individuals are unrelated.
Use the summary() method to get an overview of the
calculated matrix, including size, density, and average
relationship.
Instead of manually indexing the matrix, you can use
query_relationship() to retrieve coefficients by individual
IDs.
For large pedigrees with many full-sibling families (common in
aquatic breeding populations), pedmat() can merge full
siblings into representative nodes to save memory and time.
compact = TRUEWhen compact = TRUE, the matrix is calculated for unique
representative individuals from each full-sib family.
# Calculate compacted A matrix
mat_compact <- pedmat(tped, method = "A", compact = TRUE)
# The result is a 'pedmat' object containing the compacted matrix
print(mat_compact[11:20,11:20])
#> 10 x 10 Matrix of class "dgeMatrix"
#> D E P Q G H K L M S
#> D 1.00 0.50 0.00 0.0 0.250 0.250 0.250 0.250 0.250 0.00
#> E 0.50 1.00 0.00 0.0 0.500 0.500 0.250 0.250 0.250 0.00
#> P 0.00 0.00 1.00 0.5 0.000 0.000 0.000 0.000 0.000 0.25
#> Q 0.00 0.00 0.50 1.0 0.000 0.000 0.000 0.000 0.000 0.50
#> G 0.25 0.50 0.00 0.0 1.000 0.500 0.125 0.125 0.125 0.00
#> H 0.25 0.50 0.00 0.0 0.500 1.000 0.125 0.125 0.125 0.00
#> K 0.25 0.25 0.00 0.0 0.125 0.125 1.000 0.500 0.500 0.00
#> L 0.25 0.25 0.00 0.0 0.125 0.125 0.500 1.000 0.500 0.00
#> M 0.25 0.25 0.00 0.0 0.125 0.125 0.500 0.500 1.000 0.00
#> S 0.00 0.00 0.25 0.5 0.000 0.000 0.000 0.000 0.000 1.00If you need the full matrix after a compact calculation, use
expand_pedmat(). For retrieving specific values,
query_relationship() handles both standard and compact
objects transparently.
Compact mode is highly recommended for:
| Pedigree Size | Full-Sib Proportion | Recommended Mode |
|---|---|---|
| < 1,000 | Any | Standard |
| > 5,000 | < 20% | Standard / Compact |
| > 5,000 | > 20% | Compact |
vismat()Visualization helps in understanding population structure, detecting family clusters, and checking the distribution of genetic relationships.
The "heatmap" type (default) uses a Nature Genetics
style color palette (White–Orange–Red) to display relationships. Rows
and columns are reordered by hierarchical clustering (Ward.D2) by
default, bringing closely related individuals into contiguous blocks —
full-sibs cluster tightly because they share nearly identical
relationship profiles with the rest of the population.
A compact pedmat object can be passed directly to
vismat(). It is automatically expanded to full dimensions
before rendering.
# Compact matrix: expanded automatically (message printed)
vismat(mat_compact,labelcex=0.5)
#> Expanding compact matrix (27 -> 28 individuals) for visualization.Set reorder = FALSE to keep the original pedigree order
instead of re-sorting by clustering.
Use ids to focus on specific individuals.
target_ids <- rownames(as.matrix(mat_A))[1:8]
vismat(mat_A, ids = target_ids,
main = "Relationship Heatmap — First 8 Individuals")For large populations, aggregate relationships to a group-level view
using the by parameter. The matrix is reduced to mean
coefficients between groups.
# Mean relationship between generations
vismat(mat_A, ped = tped, by = "Gen",
main = "Mean Relationship Between Generations")
#> Aggregating 28 individuals into 6 groups based on 'Gen'...# Mean relationship between full-sib families
# (founders without a family assignment are excluded automatically)
vismat(mat_A, ped = tped, by = "Family",
main = "Mean Relationship Between Full-Sib Families")
#> Note: Excluding 9 founder(s) with no family assignment: J1, O, N, F, R (and 4 more)
#> Aggregating 19 individuals into 11 groups based on 'Family'...Calculation and visualization of large matrices can be
resource-intensive. vismat() applies the following
automatic optimizations:
| Condition | Behavior |
|---|---|
Compact + by |
Group means are computed directly from the compact matrix (no full expansion) |
Compact, no by, N > 5 000 |
Uses compact representative view (labels show
ID (×n)) |
Compact, no by, N ≤ 5 000 |
Matrix is automatically expanded via
expand_pedmat() |
| N > 2 000 | Hierarchical clustering (reorder) is automatically skipped |
| N > 500 | Individual labels are automatically hidden |
| N > 100 | Grid lines are automatically hidden |
When a compact pedmat is used with by,
vismat() computes the group-level mean relationship matrix
algebraically from the K×K compact matrix, including a sibling
off-diagonal correction. This avoids expanding to the full N×N matrix,
making family-level or generation-level visualization feasible even for
pedigrees with hundreds of thousands of individuals.
The example below uses big_family_size_ped (178 431
individuals, compact to 2 626) and displays the mean additive
relationship among all full-sib families in the latest
generation — a computation that would be infeasible with full
expansion.
data(big_family_size_ped)
tp_big <- tidyped(big_family_size_ped)
last_gen <- max(tp_big$Gen, na.rm = TRUE)
# Compute the compact A matrix for the entire pedigree
mat_big_compact <- pedmat(tp_big, method = "A", compact = TRUE)
# Focus on all individuals in the last generation that belong to a family
ids_last_gen <- tp_big[Gen == last_gen & !is.na(Family), Ind]
# vismat() aggregates directly from the compact matrix — no expansion needed
vismat(
mat_big_compact,
ped = tp_big,
ids = ids_last_gen,
by = "Family",
labelcex = 0.3,
main = paste("Mean Relationship Between All Families in Generation", last_gen)
)
#> Aggregating 37009 individuals into 106 groups based on 'Family'...This family-level view reveals the genetic structure among all 106 families comprising 37009 individuals, computed in seconds from the compact matrix.
See Also: -
vignette("tidy-pedigree", package = "visPedigree") -
vignette("draw-pedigree", package = "visPedigree")