Skip to contents

For every animal whose sire or dam is genotyped together with it, counts the markers called in both and, among them, the opposite homozygotes (0 in one, 2 in the other), which Mendel forbids between a parent and its offspring, genotyping error aside. A rate above exclusion_threshold says the pedigree or the sample is wrong: a parent recorded by mistake, a sample swap. The rule and the default 1% are the exclusion test of preGSf90 (verify_parentage, exclusion_threshold 1; Hayes 2011), with one difference: preGSf90 divides by every SNP, and here the denominator is the markers called in both, so a pair with many missing calls is not diluted. A true pair shows only the genotyping error, and an unrelated pair 2 p^2 q^2 per marker (12.5% at p = 0.5), some 5% to 10% over a common panel. The column of maternal grandsires of a sire_mgs() pedigree is left out, since grandparent and grandchild can be opposite homozygotes.

Usage

parentage_check(
  pedigree,
  genotypes,
  exclusion_threshold = 0.01,
  sex_markers = genotypes[["sex_markers", exact = TRUE]]
)

Arguments

pedigree

data.frame animal, sire, dam (or a sire_mgs() pedigree). A repeated animal is refused; a genotyped animal missing from it is a warning, and none at all an error, because no pair would read as no conflict

genotypes

list with ids and m (0/1/2, NA for missing), and optionally sex_markers

exclusion_threshold

fraction of opposite homozygotes, among the markers called in both, above which the pair is a conflict

sex_markers

the columns of m on the sex chromosomes (indices, names or a logical vector), left out of the test; by default genotypes$sex_markers, and NULL tests every marker

Value

a data.frame with one row per genotyped parent-offspring pair, in pedigree order: id (the offspring), parent, type ("sire" or "dam"), markers (called in both), opposite (opposite homozygotes), rate (their fraction) and conflict (rate > exclusion_threshold)

Details

Use autosomal markers: PLINK codes a male hemizygous X as homozygous, and a son takes his X from the dam, so a sire and son are opposite homozygotes on about 2pq of the X markers with no error at all; with 3% of a chip on the X that alone is about 1%, the threshold. preGSf90 skips the sex chromosomes in this test (sex_chr); here sex_markers = does it, with the map that read_plink() returns, or a genotypes$sex_markers element, which qc_genotypes() sets when it is given them.

Unlike the fitters, this function does not refuse an animal with a low call rate: it imputes nothing, and each pair is counted over the markers called in both.

Every single-step fitter runs the same check, on every marker it is given but those that genotypes$sex_markers names, and warns, naming the pairs, when one exceeds 1%; it then fits the data as given. The two remedies: set the wrong parent unknown in the pedigree (below), or drop the offspring's genotype, which is what preGSf90 does by default and what qc_genotypes(genotypes, pedigree = ) does. options(BreedingR.verify_parentage = FALSE) (or 0, the verify_parentage 0 of preGSf90) turns the fitters' check off, for genotypes simulated without the pedigree, where every pair conflicts by construction; this function and qc_genotypes() still run it.

References

Hayes, B.J. (2011). Technical note: Efficient parentage assignment and pedigree reconstruction with dense single nucleotide polymorphism data. Journal of Dairy Science 94:2114-2117.

Misztal, I. et al. (2018). Manual for BLUPF90 family of programs, preGSf90 (verify_parentage, exclusion_threshold, sex_chr).

Examples

s <- simulate_breeding(20, 2, 20, n_markers = 300, seed = 1)
g <- s$genotypes
ped <- s$pedigree
# a wrong sire for the first genotyped offspring
filho <- which(ped$sire %in% g$ids & ped$id %in% g$ids)[1]
ped$sire[filho] <- setdiff(g$ids, c(ped$id[filho], ped$sire[filho]))[1]
ck <- parentage_check(ped, g)
ck[ck$conflict, ]
#>       id parent type markers opposite       rate conflict
#> 1 G1_001   F001 sire     300       23 0.07666667     TRUE
# one remedy: the parent in conflict becomes unknown
ruim <- ck[ck$conflict & ck$type == "sire", ]
ped$sire[match(ruim$id, ped$id)] <- "0"