Genomic data encoding

A prediction model cannot compare a training animal with a candidate unless their genotypes use exactly the same representation. This page turns marker states into matrices while keeping a coding convention separate from biological meaning.

SNP dosage counts a chosen allele

At a biallelic SNP, let \(M_{ij}\) be the number of copies of a chosen counted allele carried by individual \(i\) at marker \(j\). Thus \(M_{ij}\) is 0, 1, or 2. The reference and counted alleles are labels: reversing them changes the numbers and coefficient signs, but not the individual’s DNA or the evidence that a locus is causal. For \(n\) animals and \(p\) SNPs, \(\mathbf M\) is an \(n\times p\) dosage matrix and the allele frequency is

\[f_j=\frac{1}{2n}\sum_{i=1}^{n}M_{ij}.\]

Centred coding removes the expected dosage under the chosen reference population,

\[W_{ij}=M_{ij}-2f_j,\]

giving an \(n\times p\) matrix \(\mathbf W\). Optional variance scaling changes the relative weighting of marker columns and must be stated. Missing calls need a documented imputation or model strategy; silently treating them as zero copies changes allele frequencies and similarity.

Code
d <- readRDS("../../demo-data/main/demo_data.rds")
M <- d$snp[1:6, c("SNP007", "SNP008", "SNP017"), drop = FALSE]
allele_frequency <- colMeans(M) / 2
W <- sweep(M, 2, 2 * allele_frequency, FUN = "-")
M
       SNP007 SNP008 SNP017
IND001      0      1      1
IND002      0      1      1
IND003      2      0      0
IND004      1      0      2
IND005      0      1      0
IND006      0      2      1
Code
allele_frequency
   SNP007    SNP008    SNP017 
0.2500000 0.4166667 0.4166667 
Code
       SNP007        SNP008        SNP017 
 0.000000e+00 -5.551115e-17 -5.551115e-17 

The three frequencies in this six-animal teaching view are 0.25, 0.417, and 0.417. The centred column means are zero apart from floating-point rounding. For prediction, frequencies and imputation values must be estimated from the training population and then applied unchanged to candidates. Re-estimating them in a test set changes the fitted representation and can leak information.

A microhaplotype is categorical before it is encoded

A phased microhaplotype records one local haplotype state on each chromosome copy. Its stored identifiers are category labels, not dosages: identifier 8 is not twice identifier 4. For block \(b\) and allele \(k\), let \(c_{ibk}\) be the number of copies carried by individual \(i\) and let \(p_{bk}\) be its frequency. Following the additive haplotype coding of Da (2015), the column for a non-baseline allele is

\[ W^{\alpha h}_{ibk}=2p_{bk}-c_{ibk}= \begin{cases} -2(1-p_{bk}), & c_{ibk}=2,\\ -(1-2p_{bk}), & c_{ibk}=1,\\ 2p_{bk}, & c_{ibk}=0. \end{cases} \]

The most frequent allele at each block is omitted as a baseline, avoiding perfect multicollinearity; its contribution is represented by the intercept and the remaining allele columns. The sign is a coding convention. Reversing all columns changes effect signs but leaves a relationship matrix formed from \(\mathbf W_{\alpha h}\mathbf W_{\alpha h}^{\mathsf T}\) unchanged.

Code
mh <- d$mh[1:6, 5:6, drop = FALSE]
colnames(mh) <- c("block_3_copy_1", "block_3_copy_2")
alleles <- sort(unique(as.vector(mh)))
mh_counts <- sapply(alleles, function(a) rowSums(mh == a))
colnames(mh_counts) <- as.character(alleles)
mh_frequency <- colMeans(mh_counts) / 2
baseline_allele <- names(which.max(mh_frequency))
non_baseline <- setdiff(colnames(mh_counts), baseline_allele)
stopifnot(length(non_baseline) > 0L)
W_alpha_h <- sweep(
  mh_counts[, non_baseline, drop = FALSE],
  2,
  2 * mh_frequency[non_baseline],
  FUN = function(count, expected) expected - count
)
stopifnot(all(is.finite(W_alpha_h)))
mh
       block_3_copy_1 block_3_copy_2
IND001              8              4
IND002              8              4
IND003              7              4
IND004              8              4
IND005              8              4
IND006              8              4
Code
mh_counts
       4 7 8
IND001 1 0 1
IND002 1 0 1
IND003 1 1 0
IND004 1 0 1
IND005 1 0 1
IND006 1 0 1
Code
mh_frequency
         4          7          8 
0.50000000 0.08333333 0.41666667 
Code
baseline_allele
[1] "4"
Code
W_alpha_h
                7          8
IND001  0.1666667 -0.1666667
IND002  0.1666667 -0.1666667
IND003 -0.8333333  0.8333333
IND004  0.1666667 -0.1666667
IND005  0.1666667 -0.1666667
IND006  0.1666667 -0.1666667

The project representation contains labels 4, 7, and 8 in this block. The count matrix says how many copies of each label occur; it does not say that allele 8 is quantitatively larger than allele 4. The displayed \(\mathbf W_{\alpha h}\) uses all non-baseline allele columns for this one block; a full panel concatenates the corresponding columns across blocks. The haplotype and microhaplotype input guide explains how phase and compact input objects are obtained.

Encoding fixes the comparison population

Centred SNP columns and multiallelic allele-count columns are both statistical representations. They depend on marker order, allele definitions, phase, and the population used for frequency estimates. They do not by themselves prove identity by descent, establish a causal variant, or make one marker type universally better. The next page uses the centred SNP matrix to describe realised genomic similarity through a genomic relationship matrix.

Exercises

  1. A SNP has counted-allele dosage 2. What happens to its dosage if the other allele becomes the counted allele?

It becomes 0. The coding changes from \(M\) to \(2-M\), but the diploid genotype and biological evidence do not change.

  1. Why must a candidate use allele frequencies estimated in the training population?

The fitted parameters refer to the training-derived centring. Re-estimating frequencies in candidates changes the columns supplied to the model and can leak information during evaluation.

  1. Why is it invalid to regress directly on a compact haplotype label such as 4, 7, or 8?

The labels identify categories, not ordered measurements. A direct numeric slope would impose artificial distances between haplotype states.