Fit a mixed model by AI-REML
Usage
model(
formula,
data,
pedigree = NULL,
genotypes = NULL,
blend = 0.05,
apy_core = NULL,
missing_code = NULL,
maxiter = 300L,
tol = 1e-08,
n_em = 4L,
metafounders = NULL,
gamma = NULL,
verbose = interactive(),
weights = NULL,
start = NULL,
residual_by = NULL
)Arguments
- formula
for example
peso ~ cg + sexo + animal(id). An unmarked term is a fixed class effect, andfixed(cg)is the same term (it takestraits =inmodel_mt());cov(x)is a fixed covariate;animal(id),maternal(dam)andsire(sire)are random with relationship, andsire(sire, mgs = "mgs")is the sire and maternal-grandsire model, 1 on the sire and 1/2 on the maternal grandsire of the record in the same effect (an unknown grandsire, "0", leaves the sire only, and an unknown sire the grandsire only; a missing value in that column is refused, see below);pe(id)andrandom(lote)are random without relationship.group = "nome"puts two random terms in the SAME covariance matrix, with the correlation estimated. The terms of a group index one set of levels, and level l of one term covaries with level l of the other: the pedigree animals in a relationship group, and in a group of terms without a relationship matrix (random(),pe()) the union of the level names of their columns, sorted (integer labels in numeric order, then the rest). The pairing is by name, so the order of the rows does not matter, and a level that appears in only one column is still an effect of the other term, with no record there. Their covariance is estimated only through the levels that have records in both columns: with none (sire and dam ids that never repeat between the sexes) it does not enter the likelihood, and every fitter that estimates components stops before fitting and names the two terms. At given components (start =withmaxiter = 0andn_em = 0, ortheta_fixed =ingibbs()) the group is accepted.traits = "y1"on a random term is formodel_mt()only: see there. The other fitters fit one trait and stop on it. ONLY THE OBSERVATION MAY BE MISSING. A column that gives the level of a term (a fixed class, the id of a random term, the maternal grandsire ofsire(mgs =), the class of a nested covariate) may not hold a missing label on ANY row, including a row whose observation is missing:NA,NaN,Infor-Infin a numeric column, andNA, blank text (whatread.csv()gives an empty cell of a text column; spaces, tabs and line breaks alone count as blank) or the text "NaN" (whatfactor()makes of a numericNaN) in a text or factor column. Those rows would form one shared level. The texts "NA" and "Inf" are accepted, since they may be real names, and in the maternal-grandsire column blank text is the unknown grandsire, like "0". A column that enters as a VALUE, the covariate ofcov()(nested or not) and the columns ofbase =, may not holdNA,NaN,Infor-Infon any row either: the covariate would leave the model without a word. Every case stops the fit with the term, the column, the number of such rows and the first of them (a textNAwith the column and the first row); drop those rows, or fill them, before the fit. The rule is checked on every row, also where the observation is missing, so one data frame is accepted or refused alike bymodel(),model_mt(),gibbs(),snp_blup(), theeval_internalfamily andpegs()(idandenvironment =). Refusing is the conservative one of the field's conventions: ASReml stops on a missing explanatory value unless!MVINCLUDE(the missing value counts as zero) or!MVREMOVE(the record is dropped) is declared, and asreml-R defaults tona.method(y = "include", x = "fail"); BLUPF90 reads a 0 in a class column as the effect being absent from that record, so a BLUPF90 data file with 0 as its missing class code gives here one shared level "0", which cannot be refused because "0" may be a real name: drop those records, or give them their levels, before the fit. A missing observation (NA,NaN,Infor-Infin the trait, ormissing_code) with its levels and covariates present only drops its record.missing_codeis the code of the OBSERVATION only, asOPTION missingis in BLUPF90, where a data file with -999 for an unknown age in acovcolumn regresses those records on an age of -999. Here a covariate cell equal tomissing_codeis refused on every row, likeNA, with the term, the count and the first row, when the code lies more than 10 robust SDs (the median absolute deviation, scaled to the SD) from the median of the other cells of the column, the signature of a code. Closer to them it may be a real value (the 0 of a 0/1 covariate undermissing_code = 0, the BLUPF90 default), and the fit goes on with a warning that the cells enter as that value; WOMBAT likewise stops on a covariable of zero until told whether it is a value (COVZER FIT) or a missing record (IGN) (Meyer, WOMBAT manual, 2017, section 4.10.6.2). A level column holding the code is one more level "-999". Turn those cells intoNA, which stops the fit with the column and the first row, and then drop or fill those records. VALUES THAT LOOK LIKE A CODE. Before the fit, every fitter that reads a numeric trait (model(),model_mt(),gibbs(),snp_blup(), theeval_internalfamily andpegs()) warns about two patterns among the observed records, naming the trait, the count, the first row and the value: a common missing-value code (-9, -99, -999, -9999, -99999, 99, 999, 9999, 99999, or -123456789, the WOMBAT default) held by two records or more, outside the range of the other values and at least 3 robust SDs from their median; and records more than 10 robust SDs from the median. The same two patterns in a covariate, on the records with the trait observed, give a warning that names the covariate. On simulated data, ten records at -999, or three records 1e4 above the rest, took the heritability from 0.35 to 1e-10 without a word before this check. A NUMBER STAYS A NUMBER: a factor or text column read as a number (the trait, a covariate, the traits ofpegs()) is refused with the column, and not read as its codes 1, 2, ... The marker argumentbase =takes a value and not a column name. The fit evaluates it in the environment where you wrote the formula, so a formula that one function builds and another fits finds its basis. The fit keeps informulathe formula with the value ofbase =written in. Soh2()andaccuracy()read the value of the fit after the variable changes or goes away. The arguments that NAME something,group =,nome =,nested =andmgs =, are taken literally and never evaluated:group = gis the group called "g", the same asgroup = "g", and not the value of a variableg. Because a group meant by value would silently become a group of its own, a term that is alone in a group whose unquoted name is a variable of the formula's environment holding a different text is refused, with both spellings in the message; write group names in quotes.- data
data.frame with the columns referenced
- pedigree
data.frame animal, sire, dam; required with a relationship term. Ids may be numeric or text, and each column may have its own type: a numeric id is written as its full integer everywhere (the data, the pedigree, the genotypes, the matrices this package builds and the names of the results), so 100000 as a double, as an integer and as the text "100000" are one animal. A numeric id that is not an integer keeps the digits that tell it apart from every other number (1234567.5 is "1234567.5", and 123456.7 never meets 123457). Text that R wrote in scientific notation ("1e+05" is what
as.character(),factor()andrownames<-give for the double 100000) is a different label, and when the other side holds that same number the fit stops with an error rather than dropping the animal's records.THE IDS OF THE DATA AGAINST THE PEDIGREE follow one rule in every fitter (
model(),model_mt(),gibbs(),snp_blup()and theeval_internalfamily), andaccuracy(),solutions()andsnp_effects()redo it from the pedigree given, so one data frame gets one answer everywhere:an animal of the data (in any relationship term, on any row, a maternal grandsire included) with no line in the pedigree enters as a FOUNDER, with unknown parents, and a warning counts them by column and names the first. renumf90 numbers every animal with a record the same way; ASReml asks for every animal of the data in the pedigree file. When NO id of a column is in the pedigree the two use different ids, and the fit stops with the first id of each side;
the unknown code
0(or the text"NA") in the column of a relationship term is an unknown animal, as in BLUPF90, whose renumf90 readme warns that "missing animals have code 0": the effect is absent from that record (a level 0 in a BLUPF90 data file adds nothing to that effect), and the record stays in the other terms with zero incidence in this one. So a record with an unknown dam keeps its direct effect, and a message counts those records. The same 0 is absent too in ape()orrandom()term that reads the same column (the maternal permanent environment ofmaternal(dam) + pe(dam), thepe(id)ofanimal(id) + pe(id)): there it is never one shared level of unknown dams. In a column that no relationship term reads, 0 stays an ordinary level:pe(dam)with nomaternal(dam)puts every record with dam 0 in one level "0" (give those dams ids of their own, or add the relationship term, to avoid it). A term whose every row holds 0 stops the fit; insire(mgs =)a record with an unknown sire keeps only the grandsire contribution, and none when the grandsire is unknown too, and the message counts each. The fit refuses a missing value in a relationship column (NA, blank text) as in any level column, and tells you to write an unknown parent as 0;an id with no line that matches a line written another way (spaces, tabs, carriage returns or no-break spaces at the ends, upper against lower case, leading zeros, a trailing
.0, accents composed against decomposed, latin1 bytes read as UTF-8) stops the fit with both spellings and the difference: it is a mismatch, not a new animal. The same text in latin1 and in UTF-8 is one id;a numeric column that gives levels (any id column, and also a class such as a numeric contemporary-group or herd code, a nested class, a pen or a maternal grandsire), of the data, of the pedigree or of
genotypes$ids, holding values at or above 2^53 (the 16- and 17-digit ids of electronic ear tags read byread.csv()) has already lost digits: it is refused, with the column and how to read it as text. A covariate is a number and is not checked. Aninteger64column (data.table::fread()) is read as its exact digits;the pedigree is PRUNED to the animals of the data (every row, the trait observed or not), the genotyped and all their ancestors, the informative set renumf90 extracts ("genotyped and phenotyped animals + their ancestors traced back") with a
PED_DEPTHdeep enough to reach every ancestor (its default, 3, keeps three generations; 0 loads the whole pedigree), and a message counts the lines left out. The pruning is exact for the likelihood and for every breeding value kept. An animal left out (no record, no genotype, no recorded descendant: a young candidate) has NO breeding value in the fit: give it a row of the data with the trait missing, its other columns filled, to keep it. A national pedigree far larger than the data no longer reaches the factorization;when the records form blocks with no genetic link between them (no relationship through the pedigree nor the genotypes) and the fixed effects give a block levels of its own, a warning says so: any genetic difference between the blocks is absorbed by those effects, and the breeding values compare only within a block (Fernando, Gianola and Grossman 1983; Kennedy and Trus 1993).
solutions()then has ablockcolumn
- genotypes
list with
idsandmfor single-step: animals x markers coded 0/1/2, as a double, integer or raw matrix. NA (5 in a raw matrix, the BLUPF90 code) is imputed with the marker mean, never converted to zero. The matrix is read where it is, without a copy, so a raw one costs 1 byte per genotype (read_blupf90_snp()andread_plink(storage = "raw")return it). Every function that takesgenotypes =checks the same things and refuses, naming the animals: genotypes without animals or without markers (passgenotypes = NULLfor a fit on the pedigree alone), a missing or repeated id inids(one genotype per animal), rownames ofmthat contradictids(the genotype goes to the animal at its position inids), and, everywhere a missing genotype is imputed by the mean, an animal with a call rate below 0.90: such a row is mostly marker means and looks like an average, accurately known animal. The 0.90 is thecallrateAnimdefault of preGSf90, but the rate is counted over the markers that vary (the ones that enter G), where preGSf90 counts every SNP: on a monomorphic marker the mean imputes the genotype every animal carries. The output ofqc_genotypes()always passes this check;options(uaitrem.min_call_rate_animal =)moves the line, and 0 turns it off. With a pedigree, a genotyped parent and offspring with opposite homozygotes on more than 1% of the markers called in both (the exclusion test of preGSf90,exclusion_threshold 1) are a warning naming the pairs, and the fit goes on with the data as given; seeparentage_check(), which also says how to turn the check off and why sex-chromosome markers must be left out of that test. An optional elementgenotypes$sex_markers(column indices, names or one logical per column, asqc_genotypes()returns it when givensex_markers =) names them; they stay in G- blend
weight of A22 in the adjusted G, the usual 0.05
- apy_core
ids of the genotyped animals that form the APY core; with it the inverse of G* is the APY approximation (cost in the size of the core, not cubic in the genotyped) and the result message SAYS it is an approximation and with which core (its size is part of the result).
"auto"chooses the core withapy_core_select(): as many animals as eigenvalues of G explaining 98% of its trace, drawn at random- missing_code
missing-value code for observations, for example -999. It applies to the trait only: in a level column the code is an ordinary level, and in a covariate a cell at the code is refused when it lies far from the other values and warned about otherwise (see the missing-value rule under
formula)- maxiter
maximum number of iterations of the damped step. The default 300 was raised from 100 after a measured case: a model warm-started from the reduced fit still had relDelta 1.6e-4 at iteration 100, no defect, a model that walks slowly along a covariance boundary. A fit that hits the ceiling says so in
messageand reportsconverged = FALSE, with one exception: when the Newton decrement at the last point is below its tolerance, the fit is certified on a flat direction of the likelihood. Thenconverged = TRUEat the ceiling, andmessagesays that the components were still moving. The walk also stops before the ceiling when 25 iterations in a row give no gain above 1e-8 of the -2logL and no EM step moves, with the same verdict as at the ceiling.maxiter = 0evaluates the start (after then_emEM rounds) and always reportsconverged = FALSE: an evaluation is not a convergence, whatever the Newton decrement at that point, whichmessagegives- tol
RELATIVE tolerance on the components, sqrt(sum delta^2 / sum theta^2). BLUPF90 note: airemlf90/blupf90+ VCE test the SQUARED quantity, so their conv_crit equals this tol squared (their 1e-10 is tol = 1e-5 here; this 1e-8 default is 1e-16 on their scale). A small step alone never certifies convergence:
converged = TRUEadditionally requires the Newton decrement of the free components, g' AI^-1 g restricted to the components not held at a boundary, to fall under 2e-4, near the optimum the decrement is about twice the -2logL gap to it, so the certificate bounds that gap by ~1e-4. The value is reported innewton_dec. Measured motivation: a fit that stalled against the singularity boundary with relDelta 5.1e-9 and the score far from zero sat 6.9 -2logL units above the optimum, and the step criterion alone declared it converged. A component held at a boundary is left out of the decrement only when the boundary passes the Karush-Kuhn-Tucker condition of a constrained optimum. Here that is the sign of the score: a variance at its floor is excluded only with the score pushing it out of the admissible cone, and the step never freezes a component whose score points inward.model_mt()checks it on the likelihood instead, because its step also freezes a block whose curvature has collapsed, whatever the sign (seetolthere). The variance floor of the step is 1e-10 of the variance ofy, fixed for the whole walk, so the walk does not depend on the unit ofy(it was 1e-10 in the user's unit whenever the residual variance was below 1: withytimes 1e-5 the permanent-environment variance stuck on it, 27% above its optimum, and the fit was declared converged with the additive variance 14% low)- n_em
EM iterations before the AI, to land in the right basin
- metafounders
labels of unknown-parent groups; a parent with one of these labels needs no line of its own (any OTHER cited-without-line parent is still a declared error). Metafounders enter as virtual base rows of A(Gamma) after Legarra et al. (2015)
- gamma
the base relationship matrix of the metafounders. Either a vector of length
n_metafounders, read as the DIAGONAL, or a full symmetricn_metafounders x n_metafoundersmatrix. The off-diagonalgamma_jkis the ancestral relationship BETWEEN two base populations, which is what a multibreed analysis turns on; it may be NEGATIVE, for bases pulled apart by selection in opposite directions. Admissibility is positive SEMI-definiteness, tested by a spectral decomposition and not by a Cholesky, plus a diagonal below 2 so that a metafounder's offspring keeps a positive Mendelian variance. A fit needs gamma positive-definite: with a SINGULAR gamma (gamma = 0, or two metafounders whose rows are identical) a metafounder, or a combination of them, has no prior variance and leaves the mixed model equations, and the fit refuses it with the cause. For the limit of unknown parent groups give a small diagonal (gamma = 1e-6); for two labels of one population, use one label.a_inverse()takes a singular gamma, through the Moore-Penrose pseudo-inverse. An INDEFINITE gamma, a negative eigenvalue, is refused everywhere- verbose
print the fit as it walks: one line per AI iteration with the -2logL and the relative step, so a long fit is a progress report instead of silence. The relative step is half of the convergence criterion; the Newton decrement, reported in
newton_dec, is the other half. Defaults to interactive(), live in a session, quiet in scripts and checks. Every fitter also honors Ctrl+C now- weights
a column of
data, or a numeric vector: a record of weight w has residual variances2e / w. Weights enter as a row scaling by sqrt(w), so the normal equations solved are the weighted ones. Use them when records are means of different sizes, or estimates that carry their own precision, a two-step analysis, a de-regressed proof. The -2logL leaves out the term-sum(log(w))oflog|R|. So the same model written with weightsc * wand residual variancec * s2egives a -2logL larger byn * log(c), withnthe records (measured: 27.73 for c = 2 and 40 records). Compare the -2logL of fits that have the same weights only- start
starting values for the components, in the order the fit reports them. Use it to warm-start from a submodel, or to check that the optimum does not depend on where the search began. Without it the start comes from
var(y)- residual_by
name of a column of
datawhose classes (an age class, a period) get their own residual variance,var(residual|class)for each class, in the order of the sorted labels; every record with a response needs a class, and there must be 2 classes or more. The variances are estimated with the others, andh2()reads the residual at the mean over the records of the class variances (the rule of the residual of a fit withweights, which this argument does not take)
Value
an object of class breeding_fit. Besides the fields below it carries
used, one logical per row of data saying whether that record entered the
equations: n_used counts them and used says WHICH, which is what anything
that has to sum on the same base as the likelihood needs. dense_block is
c(dense = k, columns = n): the last k of the n columns of the Cholesky factor
are completely full, and each factorization costs about k^3 / 3 there. In a single
step without apy_core =, k is at least the number of genotyped animals; with it,
at least the core size plus one. The fill of the pedigree itself can add to it, and
in a small herd it dominates. In a single step it carries h_prior, the diagonal of G* of each genotyped animal, named by animal, and
h_prior_row, the row of that animal in the pedigree the fit built: the prior
variance accuracy() uses for a genotyped animal instead of 1 + F. It also carries
genomic, list(blend), which with
apy, metafounders and gamma is what snp_effects() reads to rebuild the same
G*. It carries, one value per row of data (NA where the record did not enter),
the conditional residual residual, the fitted values fitted (X b + Z u) and
fitted_fixed (X b) and the leverage leverage, which residuals.breeding_fit()
reads, with missing_code and weights as given. With a
relationship term it carries pedigree_used, list(lines, founders, kept): the
lines of the pedigree given, the ids of the data it added as founders and the
animals kept by the pruning (see pedigree), which accuracy() and snp_effects()
read to rebuild the same pedigree. When the records form blocks whose genetic
difference the fixed effects absorb it carries blocks,
list(n, records, absorbed_by, animal): the number of blocks, the records of each,
the fixed terms that give each block its own levels and the block of each animal.
The object holds
the components theta with their se,
the fixed-effect solutions b (named term=level, in the order the columns of X
entered), ebv and pev per covariance group, score, vcov, the convergence
fields (converged, iters, reldelta, and newton_dec, the Newton decrement
of the free components at the final point) and message. vcov is 2 AI^-1, the
sampling covariance of the components. A component held at a boundary (a variance at
zero, kernel(fixed =)) has no standard error, and the others come from the
information conditional on it. When a covariance group stops at a wall (a correlation
at +/-1), vcov is the covariance conditional on that wall: 2 J_F (J_F' AI J_F)^-1 J_F'. Here J is the derivative of theta in the coordinates of the step. F is the
set of coordinates off the wall, so vcov has one rank less. PARAMETRIZATION OF b, and it matters when comparing against
a book or another program: the model carries an implicit intercept and drops
linearly dependent columns (listed in dropped_x; a dropped level has solution
zero). COVARIATES ARE STANDARDIZED INSIDE: a cov() column enters the equations as
(x - mean) / SD of the used rows, as WOMBAT deviates covariables from their means
(Meyer, WOMBAT manual, 2017, section 4.8.1.1), and b comes back in the unit of the
data, the intercept taking the centre, so it equals the fit of hand-centred data
back-transformed, and -2logL keeps its value. cov(x, nested = "c") is centred too
when c is also a fixed class of the model (the levels of c, or through the
reference level the intercept and the other levels, take the centre). A date, a
POSIXct moving by minutes or a timestamp in milliseconds is thereby fitted at full
precision: before, age + 1e9 left the starting theta inadmissible, age + 3e8 gave a
regression of 5.90 against 0.0102, and age + 1e11 or age x 1e-12 went to
dropped_x. When c is not a fixed class of the model, the nested covariate is only
scaled, and a warning names it when its values sit more than 1e3 SDs from zero. When
c is a fixed class aliased with other fixed effects, so that the rank test drops
more than one level of c that has used records (for example, a herd in which c is
nested, fitted before c; a level with no used record is in dropped_x too, but it
does not count), the nested covariate is also only scaled, with no warning, and a
very large offset (around 1e7 SDs from zero) can still make the fit fail as it did
before (an inadmissible or singular starting theta). Fit c before the class it is
nested in, or leave that class out (its columns are already in the span of c). A
covariate column with no variation beyond rounding (SD up
to 100 machine epsilons of its largest value) is left as it is. The columns are
taken in the order they entered, over the records that enter
the fit (with weights, scaled by the square root of the weight), on the
standardized scale of the covariates, and a column goes
when its distance to the span of the columns kept before it is below 1e-9 of its norm
(1e-9 itself when the norm is below 1), so of a dependent set the LAST column goes:
the last level of a class against the intercept, a level with no used record, a
covariate that is a combination of earlier ones. No more columns are kept than there
are records. The design X is sparse, one entry per record and fixed term, but finding
its rank keeps a dense triangular factor of p(p + 1)/2 doubles for p kept columns,
with O(p^3) work in one thread: of the order of 0.4 GB and minutes at 10 000 fixed
columns. The factor is sized before that work for p = the candidate columns with an
entry on the used records (or the number of records, if smaller), dependent ones
included, and the fit stops with a message when that passes 4 GB (fit the largest
class as random). A column that nearly collinear columns before it span only with
very large coefficients (x1, a near copy x2 = x1 + 1e-8 z, then x1 + 1e8 (x2 - x1))
sends the rank to a dense check of up to 8 x records x columns bytes and O(n p^2)
work in one thread, which also stops with a message above 4 GB; dropping the near
copy avoids it. Unscaled polynomial covariates, or near copies on their own, stay on
the sparse route. A program that instead zeroes some other level – Mrode's examples zero one
level per factor and fit no intercept – agrees with b only on CONTRASTS,
differences between levels of the same factor, never on the raw values.
Structure checks
Before fitting, every fitter that estimates components (model(), model_mt() and
gibbs()) reads the design and STOPS on the ones the data cannot identify, naming the
term, the levels and what to do:
a random term whose levels are a function of the levels of a fixed class effect (each level of the fixed effect holds the records of a single level of the term: one sire per contemporary group, a fixed litter with
maternal(dam)orpe(dam)whenever each litter has one dam, whatever the number of litters per dam,cg = id), a random term whose records all carry the same single level (the intercept absorbs it; ape()orrandom()term with one known level and the other records on the unknown 0 of a relationship column is not absorbed and only warns, see below), or a term whose records all carry the unknown code 0 in its column. The incidence of the term is then a sum of columns of X (or zero), the fixed effect absorbs the whole term and its variance does not enter the REML likelihood. ASReml lists a random term confounded with a fixed one among the causes of a singular average information and stops unless!AISINGULARITIESis given. The unknown 0 of a relationship column has no incidence, so a level of the fixed effect that holds only unknown parents does not count against the nesting. Inmodel_mt()the check reads the rows with some trait observed and then the rows of each trait, since the fixed effects are per trait. The check takes one fixed effect at a time; a confounding by a combination of fixed effects is left to the SINGULAR verdict of the fit (seeh2()for how the extractors read it).
At given components (maxiter = 0 with n_em = 0 here, maxiter = 0 in model_mt(),
theta_fixed = in gibbs(), and snp_blup()) every design above is a warning
instead: the BLUP exists, and the data say nothing about the term beyond the components
given. maxiter = 0 with n_em > 0 moves the start by EM, which estimates, so it
stops.
The fit goes on with a warning, also written in message, when:
an
animal()term has repeated records of some animal and nope()orrandom()term reads the same column, or a column that groups the records the same way: the permanent-environment covariance between records of the same animal goes into the additive variance and inflates h2, by more the larger the share of repeated records. The warning counts the repeated animals and their records, and the advice is to addpe()of that column, the repeatability model; when less than 1% of the records repeat an animal it says that h2 moves little and asks to check for duplicated rows;a
pe()orrandom()term has fewer than 5 known levels among the records: its variance comes from that many levels and is barely determined, and labels that number something inside another unit (the parity within each dam used as the litter) merge units. A term with one known level whose other records carry the unknown 0 of a relationship term that reads the same column (maternal(dam) + pe(dam)with a single known dam) warns too, counting the records of that level: the unknown 0 has no incidence, so the intercept does not absorb the term.
These checks read the rows with an observed response that enter the analysis.
References
Patterson, H.D. & Thompson, R. (1971). Recovery of inter-block information when block sizes are unequal. Biometrika 58:545-554.
Gilmour, A.R., Thompson, R. & Cullis, B.R. (1995). Average information REML. Biometrics 51:1440-1450.
VanRaden, P.M. (2008). Efficient methods to compute genomic predictions. Journal of Dairy Science 91:4414-4423.
Aguilar, I. et al. (2010). A unified approach... Journal of Dairy Science 93:743-752; Christensen, O.F. & Lund, M.S. (2010). Genetics Selection Evolution 42:2.
Misztal, I., Legarra, A. & Aguilar, I. (2014). Using recursion to compute the inverse of the genomic relationship matrix. Journal of Dairy Science 97:3943-3952.
Fernando, R.L., Gianola, D. & Grossman, M. (1983). Identifying all connected subsets in a two-way classification without interaction. Journal of Dairy Science 66:1399-1402.
Kennedy, B.W. & Trus, D. (1993). Considerations on genetic connectedness between management units under an animal model. Journal of Animal Science 71:2341-2352.
Misztal, I. et al. The BLUPF90 family of programs, readme of renumf90 (PED_DEPTH: the genotyped and phenotyped animals and their ancestors, default 3, 0 for the whole pedigree; Warnings: missing animals have code 0). University of Georgia, https://nce.ads.uga.edu/wiki/doku.php?id=readme.renumf90