Registers an observed phenotype: the quantity written to ind_phenotype
when add_phenotype() is called. For simple (non-composite) traits,
phenotype_name equals trait_name and define_trait() must already have
been called for that name. For composite traits (e.g. weaning weight
assembled from direct and maternal components), no define_trait() call is
needed for the composite name itself.
Writes one row to phenotype_meta. If residual_var is supplied, also
writes an unconditional diagonal entry to phenotype_var_comp
(effect_name = "residual"). If components is supplied, writes one row
per component to phenotype_components.
Usage
define_phenotype(
pop,
phenotype_name,
type = c("continuous", "count", "categorical", "derived_formula"),
mean = 0,
expressed_sex = c("both", "M", "F"),
repeatable = FALSE,
min_value = NULL,
max_value = NULL,
prevalence = NULL,
thresholds = NULL,
cat_values = NULL,
cat_names = NULL,
store_liability = FALSE,
residual_var = NULL,
components = NULL,
formula_tbv = NULL,
formula = NULL,
missing_component_action = c("skip", "error"),
overwrite = FALSE
)Arguments
- pop
A
tidybreed_popobject.- phenotype_name
Character. Name of the observed phenotype; equals
trait_namefor simple (non-composite) traits.- type
Character. One of
"continuous","count","categorical", or"derived_formula"."derived_formula"phenotypes are computed atadd_phenotype()time by evaluating theformulaexpression over already- recorded phenotype values for the same individuals; they have no TBV, no residual variance, and no QTL of their own.- mean
Numeric. Phenotypic population mean (intercept). Default
0.- expressed_sex
Character. Who receives a phenotype record:
"both"(default),"M", or"F".- repeatable
Logical. Whether an individual can have multiple records for this phenotype (e.g. repeated test-day or litter-size records). Default
FALSE.- min_value, max_value
Numeric. Clipping bounds for count traits.
NULLmeans no limit.- prevalence
Numeric between 0 and 1. For categorical traits with one threshold (two categories), the fraction expected above the threshold. Mutually exclusive with
thresholds.- thresholds
Numeric vector of length K−1 for K ordered categories. Liability cutpoints in ascending order. Mutually exclusive with
prevalence.- cat_values
Numeric vector of length K. Phenotype value stored in
ind_phenotypefor each category. Defaults to1, 2, ..., K.- cat_names
Character vector of length K. Human-readable label per category, e.g.
c("Alive", "Dead"). Must not contain commas.- store_liability
Logical. When
TRUE, the underlying liability value is written to the reservedliability_valuecolumn inind_phenotype. Only meaningful for categorical traits.- residual_var
Numeric. Scalar residual variance. When supplied, writes one unconditional row to
phenotype_var_comp(effect_name = "residual",condition_column = NULL). For heterogeneous residuals or multi-phenotype correlated residuals, usedefine_residual_cov()afterwards.- components
A data frame or
tibblewith one row per genetic component. Columns:source_trait_name(required): component trait name intrait_meta.contributor_type(required):"self","dam","sire", or"group".weight(optional, default1.0): scalar multiplier.weight_type(optional, default"fixed"):"fixed","covariate","legendre", or"raw_poly".covariate_name(optional): covariate key.covariate_table(optional): table containing the covariate column;NULLmeans value supplied atadd_phenotype()call time.poly_order(optional): polynomial basis order.poly_scale_min,poly_scale_max(optional): Legendre scaling bounds.genome_effect_types(optional, default"additive").group_column(optional): column defining group membership.group_table(optional, default"ind_meta"): table containinggroup_column.aggregation(optional, default"sum"):"sum"or"mean"for group contributors.missing_action(optional, default"skip"): currently unused per-component override — behaviour is governed uniformly bymissing_component_actionbelow.contributor_filter(optional): reserved for future spatial/ neighborhood contributor lookup; not yet implemented.
NULL(default) → simple single-self trait;phenotype_componentsnot written. Mutually exclusive withformula_tbv.- formula_tbv
Character. DSL shorthand for assembling a composite TBV from component traits already in
trait_meta. A bare trait symbol (e.g."WWD") means the individual's own ("self") TBV; contributor roles can also be given explicitly as function calls:self(trait),dam(trait),sire(trait),group_sum(trait, col), andgroup_mean(trait, col)(col= grouping column inind_meta, e.g. pen or litter). These are combined with the arithmetic operators+,-,*,/, and parentheses (e.g."WWD + dam(WWM)","ADG_direct + group_sum(ADG_social, pen_id)"). Mutually exclusive withcomponents. Not valid withtype = "derived_formula".- formula
Character. Arithmetic expression evaluated over already- recorded phenotype values to produce a derived phenotype (e.g.
"ADFI / ADG"for feed conversion ratio). Phenotype names referenceind_phenotyperecords (pheno_number = 1) produced earlier in the sameadd_phenotype()call — component phenotypes must already be recorded, andadd_phenotype()topologically sorts multiplederived_formulaphenotypes so dependencies are computed first. Operators+,-,*,/,^and parentheses are supported, plus the math functionssqrt,log,log2,log10,exp,abs,round,ceiling,floor,sign,trunc,sin,cos,tan,asin,acos,atan. Non-finite results (Inf/NaN) are converted toNAwith a warning. Required whentype = "derived_formula". Not valid otherwise.- missing_component_action
Character. What to do when an individual is missing one or more required composite-TBV components (e.g. no group assignment for a
"group"contributor, or a missing dam/sire TBV)."skip"(default) excludes the individual fromind_phenotypeand emits a warning with a count."error"stops with an informative message listing affected individuals. Stored inphenotype_metaso the behaviour is consistent across alladd_phenotype()calls for this phenotype. Note: this is unrelated tonull_class_action(set viadefine_effect_fixed_class()), which handlesNULLlevels for fixed-class covariate effects, and does not affect random-effect draws (new levels always get a fresh draw).- overwrite
Logical. If
TRUEand a phenotype with the same name already exists, replace its rows inphenotype_metaandphenotype_components. DefaultFALSEerrors on duplicate.
Examples
if (FALSE) { # \dontrun{
# ── Simple continuous trait ──────────────────────────────────────────────
pop <- pop |>
define_trait("ADG", target_add_var = 100) |>
get_table("genome_meta") |>
define_additive_effects("ADG") |>
define_phenotype("ADG",
type = "continuous",
mean = 850,
residual_var = 120)
# ── Count trait with clipping bounds ────────────────────────────────────
pop <- pop |>
define_trait("NW", target_add_var = 2) |>
get_table("genome_meta") |>
define_additive_effects("NW") |>
define_phenotype("NW",
type = "count",
mean = 10,
min_value = 1,
max_value = 30,
residual_var = 8)
# ── Categorical trait (binary via prevalence) ────────────────────────────
pop <- pop |>
define_trait("mort", target_add_var = 0.05) |>
get_table("genome_meta") |>
define_additive_effects("mort") |>
define_phenotype("mort",
type = "categorical",
prevalence = 0.05,
cat_names = c("Alive", "Dead"))
# ── Maternal composite via components data frame: WW = WWD (self) + WWM (dam) ──
pop <- pop |>
define_phenotype("WW",
type = "continuous",
mean = 230,
residual_var = 180,
components = tibble::tribble(
~source_trait_name, ~contributor_type,
"WWD", "self",
"WWM", "dam"
))
# ── Maternal composite via formula_tbv shorthand (equivalent to above) ──
pop <- pop |>
define_phenotype("WW2",
type = "continuous",
mean = 230,
residual_var = 180,
formula_tbv = "WWD + dam(WWM)")
# ── SGE (social genetic effects): ADG = direct (self) + social group sum ──
pop <- pop |>
define_phenotype("ADG_sge",
type = "continuous",
mean = 850,
residual_var = 100,
formula_tbv = "ADG_direct + group_sum(ADG_social, pen_id)")
# ── Derived formula: FCR computed from already-recorded ADFI and ADG ────
# (Define ADFI and ADG first, then derive FCR — no TBV or residual needed)
pop <- pop |>
define_phenotype("FCR",
type = "derived_formula",
formula = "ADFI / ADG")
} # }
