The Domain Registry is the extensible system that replaces the legacy
switch() block for domain generation. It defines, per
domain, exactly how data should be generated: what counts to use, what
arguments to pass, and which generator function to call.
Migrating a domain to the registry makes it:
registry <- get_domain_registry()
cat("Registry-backed domains:", paste(names(registry), collapse = ", "), "\n")
# Each entry has four contract fields
cat("Raw_AE entry fields:", paste(names(registry$Raw_AE), collapse = ", "), "\n")
# > "dataset" "required_inputs" "count_fn" "generate_fn"
Every valid entry must have exactly these four fields:
| Field | Type | Description |
|---|---|---|
$dataset |
character(1) |
The Raw_* name |
$required_inputs |
character(n) |
Context keys the entry reads |
$count_fn |
function(counts, snapshot_idx) |
Picks the right count for this snapshot |
$generate_fn |
function(context) |
All generation logic; returns a data.frame |
ae_entry <- registry$Raw_AE
cat("dataset :", ae_entry$dataset, "\n")
cat("required_inputs:", paste(ae_entry$required_inputs, collapse = ", "), "\n")
# count_fn body
print(body(ae_entry$count_fn))
# generate_fn body (first 10 lines)
bdy <- deparse(body(ae_entry$generate_fn))
cat(paste(head(bdy, 10), collapse = "\n"), "\n ...\n")
Inside run_domain_generation_loop() the per-domain
dispatch is:
migrated_data <- generate_domain_from_registry(data_type, context)
if (!is.null(migrated_data)) {
data[[data_type]] <- migrated_data
next # skip the legacy dispatcher
}
# ... dispatch_legacy_domain_generator() for domains not yet in the registry
The context list passed to every
generate_fn contains:
data, previous_data, combined_specs,
n, start_date, end_date,
snapshot_idx, snapshot_count, snapshot_width, study_id
You can verify the registry path end-to-end by generating a small study:
config <- create_study_config(
study_id = "REG-DEMO-001",
participant_count = 50,
site_count = 5
) |>
set_temporal_config(
start_date = "2023-01-01",
snapshot_count = 3,
snapshot_width = "months"
) |>
add_dataset_config("Raw_AE", enabled = TRUE) |>
add_dataset_config("Raw_LB", enabled = TRUE) |>
add_dataset_config("Raw_VISIT", enabled = TRUE)
raw_data <- generate_raw_data_from_config(config, verbose = TRUE)
cat("Datasets in snapshot 1:", paste(names(raw_data[[1]]), collapse = ", "), "\n")
cat("Raw_AE rows :", nrow(raw_data[[1]]$Raw_AE), "\n")
cat("Raw_LB rows :", nrow(raw_data[[1]]$Raw_LB), "\n")
cat("Raw_VISIT rows:", nrow(raw_data[[1]]$Raw_VISIT), "\n")
To migrate a domain from the legacy dispatcher:
raw_data_generator() override or by
editing get_domain_registry() directlycase from
dispatch_legacy_domain_generator()# Example: migrating a hypothetical Raw_Biomarker domain
new_entry <- list(
dataset = "Raw_Biomarker",
required_inputs = c("data", "previous_data", "combined_specs", "n", "start_date"),
count_fn = function(counts, snapshot_idx) counts$subject_count[snapshot_idx],
generate_fn = function(context) {
spec <- context$combined_specs
data <- context$data
previous_data <- context$previous_data
n <- context$n
if ("Raw_Biomarker" %in% names(previous_data)) {
dataset <- previous_data$Raw_Biomarker
previous_row_num <- nrow(dataset)
} else {
dataset <- NULL
previous_row_num <- 0
}
n_new <- n - previous_row_num
if (n_new <= 0) return(dataset)
args <- list(
subjid = list(n_new, external_subjid = data$Raw_SUBJ$subjid),
default = list(n_new, context$start_date)
)
as.data.frame(add_new_var_data(dataset, spec$Raw_Biomarker, args, spec$Raw_Biomarker))
}
)
Equivalent generation using the explicit config helper:
config <- create_study_config(
study_id = "REGISTRY-EXAMPLE-001",
participant_count = 80,
site_count = 8
) |>
set_temporal_config(
start_date = "2012-01-01",
snapshot_count = 2,
snapshot_width = "months"
)
for (ds in c("Raw_STUDY", "Raw_SITE", "Raw_SUBJ", "Raw_ENROLL",
"Raw_VISIT", "Raw_AE", "Raw_LB")) {
config <- add_dataset_config(config, ds, enabled = TRUE)
}
raw_data <- generate_study_data(config)
raw_data_via_config <- generate_raw_data_from_config(config)
cat("Snapshots:", length(raw_data), "\n")
cat("Snapshot keys:", paste(names(raw_data), collapse = ", "), "\n")
snapshot_1 <- raw_data[[1]]
cat("Datasets in snapshot 1:", paste(names(snapshot_1), collapse = ", "), "\n")
cat("Raw_AE rows:", nrow(snapshot_1$Raw_AE), "\n")
cat("Raw_LB rows:", nrow(snapshot_1$Raw_LB), "\n")
# Wrap into a study object for helper functions
study <- create_longitudinal_study_data(
study_id = "REGISTRY-EXAMPLE-001",
raw_data = raw_data,
config = list(
participants = 80,
sites = 8,
snapshots = 2,
interval = "1 month",
domains = c("AE", "LB", "VISIT"),
study_type = "standard"
)
)
summarize_longitudinal_study(study)