Code components are the building blocks that implement the actual derivations, transformations, and calculations in your ADaM datasets. Components come in two technical formats that determine how mighty processes and executes them:
.R files).mustache files)Component metadata parsing and Mustache rendering are handled by the mighty.component package. This vignette describes the metadata format and file structure that components must follow; mighty.component is what mighty uses under the hood to read and render them. # Component types Beyond their technical format, components are classified by what they do to your data. @type takes one of four values: column, row, parameter, or internal.
Column components (@type column) create new columns in your dataset. They take existing columns as inputs and derive new variables. For example, calculating an age group from age, or computing a relative day from two dates. Column components:
@outputs)column section of your YAML ADaM specificationRow components (@type row) add new rows to your dataset or modify existing rows. For example, computing summary statistics that create new observation rows. Row components:
@outputsrow section of your YAML ADaM specificationParameter components (@type parameter) create BDS parameter records, such as adding a new PARAMCD to a BDS dataset. They are processed the same way as row components. Parameter components:
@outputsparameter section of your YAML ADaM specificationInternal components (@type internal) implement mighty’s own internal machinery, such as reading source data or initializing a domain. They are not referenced from a column, row, or parameter section of a YAML ADaM specification, and are not typically written by end users.
The key distinction between the user-facing types: column components expand your dataset horizontally (more variables), while row and parameter components expand it vertically (more records).
All components share a common structure:
The format you choose depends on whether your derivation logic needs parameterization. R scripts execute fixed logic, while Mustache templates allow you to pass parameters from your ADaM specification to customize behavior.
All components use the same metadata header structure with roxygen2-style tags. Mighty extracts this metadata to understand dependencies, outputs, and how to orchestrate components.
@titleShort descriptive title for the component.
#' @title Age Group Classification@descriptionDetailed explanation of what the component does.
#' @description Categorizes subjects into age groups based on AGE variable@paramOnly for Mustache template components - Parameters to pass to the template, populated from the with section of the ADaM specification. See vignette("adam_specification").
#' @param domain Name of the ADaM domain
#' @param cut_points Vector of age cut points@typeComponent type: "column", "row", "parameter", or "internal".
#' @type column@originCDISC origin of the column, one of "Assigned", "Collected", "Derived", "Not Available", "Other", "Predecessor", or "Protocol". Used for define.xml generation.
#' @origin Derived@methodDescription of how the column is derived, in prose. Used as the method description for define.xml generation.
#' @method Age cut into the groups < 18, 18-64, 65-74 and >= 75 years.@dependsInput dependencies listing the required columns. Format: DOMAIN COLUMN1
Multiple depends are listed on separate lines:
#' @depends ADSL AGE
#' @depends ADLB LBSTRESNMighty uses this for dependency analysis and execution ordering.
@outputsIf the component is a column derivation, this specifies which column(s) the component creates. If the component is a row/parameter action, this specifies which column(s) the component modifies
Multiple outputs are listed on separate lines.
#' @outputs AGE_GRP1
#' @outputs COL1Mighty uses this to track what each component produces or modifies.
@codeMarker indicating where the executable code (the component body) begins. All code must come after this tag.
#' @code
# Your R code here
ADSL <- ADSL |> dplyr::mutate(...)R script components contain plain executable R code with fixed derivation logic. They are saved as .R files and execute the same way every time they are called.
Use R script components when:
@code tag#') for metadata#) can be used within the code#' @title Age Group Classification
#' @description Categorizes subjects into age groups based on AGE variable
#' @type column
#' @origin Derived
#' @method Age cut into the groups < 18, 18-64, 65-74 and >= 75 years.
#' @depends ADSL AGE
#' @outputs AGE_GRP1
#' @code
ADSL <- ADSL |>
# This is an example comment
dplyr::mutate(
AGE_GRP1 = cut(
AGE,
breaks = c(-Inf, 18, 65, 75, Inf),
labels = c("< 18 years", "18 - 64 years", "65 - 74 years", ">= 75 years"),
right = FALSE
)
)Components can depend on other derived columns:
#' @title Age Category Classification
#' @description Further categorizes age groups into expected vs unexpected ranges
#' @type column
#' @origin Derived
#' @method Age groups < 18 and >= 75 years are flagged as outside the expected range.
#' @depends ADSL AGE_GRP1
#' @outputs AGE_CAT1
#' @code
ADSL <- ADSL |>
dplyr::mutate(
AGE_CAT1 = dplyr::case_when(
AGE_GRP1 %in% c("< 18 years", ">= 75 years") ~ "Outside expected range",
TRUE ~ "Inside expected range"
)
)Components can depend on multiple columns from multiple datasets:
#' @title Minimum AVAL per Subject
#' @description Derives the minimum lab value for each subject from ADLB
#' @type column
#' @origin Derived
#' @method Lowest AVAL recorded for the subject in ADLB.
#' @depends ADSL USUBJID
#' @depends ADLB USUBJID
#' @depends ADLB AVAL
#' @outputs MIN_AVAL
#' @code
ADSL <- ADSL |>
dplyr::left_join(
ADLB |>
dplyr::select(USUBJID, AVAL) |>
dplyr::group_by(USUBJID) |>
dplyr::summarise(MIN_AVAL = min(AVAL, na.rm = TRUE)) |>
dplyr::ungroup(),
by = "USUBJID"
)Mustache template components use Mustache syntax to enable parameterization. They are saved as .mustache files and allow the same component logic to be reused with different parameters.
Use Mustache template components when:
Mustache templates use triple curly braces {{{variable}}} as placeholders that get replaced with actual values when mighty renders the component. Triple braces avoid HTML escaping, which would corrupt R operators such as <- and > in generated code. See Template syntax in the special components vignette for a full explanation of double vs. triple mustache syntax.
with: section of your YAML specification@param tags to document expected parameters@depends, @outputs, and the code bodyTemplate file: relative_day.mustache
#' @title Analysis relative day
#' @description
#' Derives the relative day compared to the treatment start date.
#'
#' @param domain Name of ADaM domain
#' @param variable Name of new variable to create
#' @param date Name of date variable to use
#' @type column
#' @origin Derived
#' @method Number of days from TRTSDT to {{{date}}}, counting both endpoints.
#' @depends {{{domain}}} {{{date}}}
#' @depends {{{domain}}} TRTSDT
#' @outputs {{{variable}}}
#' @code
{{{domain}}} <- {{{domain}}} |>
dplyr::mutate(
{{{variable}}} = admiral::compute_duration(
start_date = TRTSDT,
end_date = {{{date}}},
in_unit = "days",
out_unit = "days",
add_one = TRUE
)
)Usage in ADaM specification:
columns:
- id: ADYDT
component:
id: relative_day.mustache
with:
domain: ADVS
date: ADT
variable: ADYDTRendered output (what mighty sees):
#' @title Analysis relative day
#' @description
#' Derives the relative day compared to the treatment start date.
#'
#' @param domain Name of ADaM domain
#' @param variable Name of new variable to create
#' @param date Name of date variable to use
#' @type column
#' @origin Derived
#' @method Number of days from TRTSDT to ADT, counting both endpoints.
#' @depends ADVS ADT
#' @depends ADVS TRTSDT
#' @outputs ADYDT
#' @code
ADVS <- ADVS |>
dplyr::mutate(
ADYDT = admiral::compute_duration(
start_date = TRTSDT,
end_date = ADT,
in_unit = "days",
out_unit = "days",
add_one = TRUE
)
)The same Mustache template can be used multiple times with different parameters:
columns:
- id: ADYDT
component:
id: relative_day.mustache
with:
domain: ADVS
date: ADT
variable: ADYDT
- id: ASTDY
component:
id: relative_day.mustache
with:
domain: ADVS
date: ASTDT
variable: ASTDYFor the full rules on how mighty handles component reuse in ADaM specifications — including restrictions on overlapping outputs — see Component reuse rules.
The YAML specification contains only columns that appear in the final ADaM dataset (see No intermediate columns). Components often need source columns that are not in the final dataset — for example, an SDTM character date used to derive an analysis date.
When a component declares @depends DOMAIN COLUMN, mighty adds that column to the data-reading step of the generated program. The column is available inside the component’s code without appearing in the YAML columns section. This is the intended mechanism for accessing source data that does not belong in the final output.
For example, a component that derives ASTDT and ASTDTF from the SDTM character date LBDTC:
#' @title Convert DTC to DT
#' @description Converts DTC to date (DT) format and computes the corresponding date flag (DTF) for the ADLB dataset.
#' @type column
#' @origin Derived
#' @method Analysis start date and date flag derived from the SDTM LBDTC character date.
#' @depends LB USUBJID
#' @depends LB STUDYID
#' @depends LB LBSEQ
#' @depends LB LBDTC
#' @depends ADLB USUBJID
#' @depends ADLB STUDYID
#' @depends ADLB LBSEQ
#' @outputs ASTDT
#' @outputs ASTDTF
#' @code
ADLB <- ADLB |>
dplyr::left_join(
LB |>
dplyr::mutate(
ASTDT = admiral::convert_dtc_to_dt(
dtc = LBDTC,
highest_imputation = "M",
date_imputation = "first"
),
ASTDTF = admiral::compute_dtf(
dtc = LBDTC,
dt = ASTDT
)
),
by = c("USUBJID", "STUDYID", "LBSEQ")
)
Mighty reads LBDTC from the source domain because the component declares @depends LB LBDTC, even though LBDTC has no entry in the YAML columns section.
This approach may cause the same source column to be joined more than once across different components. This is an accepted trade-off:
The classification of a component as either Standard or Custom is determined only by the governance of standard components. Mighty treats all components the same. Standard components and custom components can be either .mustache files or .R files.
Mighty looks up the id of a component in the repositories listed under repos in _mighty.yml. To use a custom component, add the directory that contains it to repos. See vignette("mighty_config") for the lookup rules.
A small number of in-built components provide core functionality managed by mighty itself:
_mighty.yml external_dataThese are automatically generated and inserted by mighty as part of the program generation process.