
Define additive QTL effects for one or more traits
Source:R/define_additive_effects.R
define_additive_effects.RdSelects QTL from a filtered genome_meta table and writes additive effects
to the genome_effects table.
Single trait (trait_name length 1) — two modes:
Manual: pass
effects, a numeric vector of lengthn_qtl(number of filtered loci) in ascendinglocus_idorder.Sampled: draw effects from
distribution("normal"or"gamma"). Ifscale_to_target = TRUE, effects are rescaled using the Falconer formula so the expected additive variance in the base population equals thetarget_add_varstored for this trait.
Multiple traits (trait_name length >= 2) — effects are drawn jointly
from a multivariate normal distribution keyed by the additive-genetic
covariance matrix G. Two locus-selection methods:
method = "shared"— the loci intblbecome the shared QTL set for all traits. Loci that are QTL for only a subset of traits ingenome_effectsalso receive independent draws (with the diagonal variance ofGfor that trait).method = "union"— the loci intblform the candidate pool; per-trait membership is determined from existing rows ingenome_effects.
The base argument controls which allele frequencies are used:
"founder_haplotypes"(default) — computes allele frequencies directly from thefounder_haplotypestable (requiresdefine_founder_haplotypes()was called). Restrict to one founder pool withbase_line_name. (This does not readgenome_meta.founder_allele_freq, which is informational only.)"current_pop"— computes allele frequencies from the currentind_haplotypetable. Pass a filteredtidybreed_tableviabase_tblto restrict which individuals define the base population.
Arguments
- tbl
A
tidybreed_tablefromget_table()("genome_meta")(with an optionaldplyr::filter()). The filtered rows determine which loci are QTL.- trait_name
Character scalar or vector. Name(s) of existing traits in
trait_meta. When length >= 2, effects are drawn jointly fromMVN(0, G)andG/methodbecome active.- effects
Optional numeric vector of length
n_qtl(manual mode, single trait only), in ascendinglocus_idorder. Error iflength(trait_name) > 1.- distribution
Character.
"normal"(default) or"gamma", used wheneffectsisNULLandlength(trait_name) == 1. Ignored for multi-trait.- G
Optional numeric matrix of additive-genetic (co)variances (multi-trait only). Must be square and symmetric with side length
length(trait_name). When supplied, stored totrait_var_compunder"gen_add". WhenNULL, read fromtrait_var_comp.- method
Character.
"shared"(default) or"union". Multi-trait only."shared"— all listed traits use the filtered loci as their shared QTL set."union"— per-trait QTL sets are read from existinggenome_effectsrows, restricted to the filtered loci.- base
Character.
"founder_haplotypes"(default) or"current_pop".- base_tbl
Optional
tidybreed_table(fromget_table()on any table with anid_indcolumn) used whenbase = "current_pop"to restrict which individuals define the base allele frequencies. WhenNULL, all individuals inind_haplotypeare used. Ignored (with a warning) whenbase = "founder_haplotypes"— usebase_line_namethere.- base_line_name
Optional character,
base = "founder_haplotypes"only. Which founder pool defines the base allele frequencies. Defaults toline_name, so line-specific effects are centered on their own line; passNULLexplicitly to pool every line instead. Errors if nofounder_haplotypesrows carry that line. See Which population centers the effects above.- line_name
Optional character. When set, effects are tagged to this genetic line:
add_tbv()then prefers these rows for alleles whoseline_originmatches, falling back per-locus to the population-wide rows. Also becomes the default forbase_line_name.NULL(default) means population-wide effects.- scale_to_target
Logical. If
TRUE, rescale effects using the Falconer formula so the expected additive variance equals the storedtarget_add_var.- seed
Optional integer for reproducibility.
Which population centers the effects
Base allele frequencies center the true breeding value (the Falconer
allele - p term) and set the 2pq denominator used by scale_to_target.
By default they come from the population the effect applies to:
base_line_name inherits line_name, so a line-specific effect is centered
on that line's own founder pool and a population-wide effect
(line_name = NULL) on the whole founder base.
This matters because pooling divergent lines overstates within-line
heterozygosity — the Wahlund effect. Two lines fixed for opposite alleles
each have zero within-line variance, but pool to p = 0.5 and an apparent
2pq = 0.5; the inflated denominator then makes scale_to_target under-scale
the effects, and realized within-line additive variance falls short of
target_add_var. Pass base_line_name = NULL explicitly to force pooling
anyway.
The centering constant is stored per row in genome_effects.base_allele_freq
and travels with its genome_value, so add_tbv() applies each allele's own
line's centering — a crossbred animal's line-A alleles are centered on line A
and its line-B alleles on line B.
Calling this function again for the same (trait_name, genome_effect_type, line_name) replaces the existing rows in genome_effects.
Examples
if (FALSE) { # \dontrun{
# Single trait — all loci on chr 1-5 become QTL; scale to target variance
pop <- pop |>
define_trait("ADG", target_add_var = 0.25) |>
get_table("genome_meta") |>
dplyr::filter(chr %in% 1:5) |>
define_additive_effects("ADG", distribution = "normal")
# Multiple correlated traits — shared QTL set, joint MVN draw
G <- matrix(c(0.25, 0.10, 0.10, 0.30), 2, 2,
dimnames = list(c("ADG", "BW"), c("ADG", "BW")))
pop <- pop |>
define_effect_cov_matrix("gen_add", G) |>
get_table("genome_meta") |>
dplyr::filter(chr %in% 1:5) |>
define_additive_effects(c("ADG", "BW"), G = G)
# current_pop: use generation-0 individuals to define base allele frequencies
gen0_tbl <- get_table(pop, "ind_meta") |> dplyr::filter(gen == 0L)
pop <- pop |>
get_table("genome_meta") |>
dplyr::filter(chr %in% 1:5) |>
define_additive_effects("ADG", base = "current_pop", base_tbl = gen0_tbl)
# Crossbreeding: each line's effects centered on its own founder pool.
# base_line_name inherits line_name, so nothing extra is needed.
pop <- pop |>
get_table("genome_meta") |> dplyr::filter(chr %in% 1:5) |>
define_additive_effects("ADG", line_name = "Duroc")
pop <- pop |>
get_table("genome_meta") |> dplyr::filter(chr %in% 1:5) |>
define_additive_effects("ADG", line_name = "Landrace")
# Line-specific effects, but deliberately centered on the pooled base
pop <- pop |>
get_table("genome_meta") |> dplyr::filter(chr %in% 1:5) |>
define_additive_effects("ADG", line_name = "Duroc", base_line_name = NULL)
} # }