## ----setup, include = FALSE---------------------------------------------------
knitr::opts_chunk$set(collapse = TRUE, comment = "#>")
library(lineager)

## ----setup-pipeline-----------------------------------------------------------
lg_start(study_id = "TRIAL-001", analysis_id = "primary-efficacy")

# Source data — patients and lab measurements
patients <- data.frame(
  USUBJID = sprintf("PT-%03d", 1:15),
  age = c(
    22L, 45L, 38L, 61L, 29L, 55L, 43L, 17L, 52L,
    34L, 48L, 27L, 66L, 39L, 51L
  ),
  sex = rep(c("M", "F", "M"), 5L),
  arm = c(
    "TRT", "TRT", "CTL", "TRT", "CTL", "CTL", "TRT", "TRT",
    "CTL", "TRT", "CTL", "TRT", "CTL", "CTL", "TRT"
  ),
  enrolled = c(rep(TRUE, 13), FALSE, FALSE),
  dosed = c(rep(TRUE, 10), FALSE, TRUE, TRUE, FALSE, FALSE),
  stringsAsFactors = FALSE
)

labs <- data.frame(
  USUBJID = sprintf("PT-%03d", c(1:10, 12:13)),
  baseline = round(c(
    24.1, 31.8, 28.4, 22.9, 35.2, 26.7,
    29.1, 33.4, 27.8, 25.5, 30.2, 28.9
  ), 1),
  endpoint = round(c(
    18.4, 27.1, 24.6, 19.8, NA, 22.3,
    25.4, 28.1, NA, 21.7, 26.4, 24.1
  ), 1),
  stringsAsFactors = FALSE
)

# Tag
pts <- lg_tag(patients, dataset_id = "PATIENTS", label = "Patient registry")
labs_tagged <- lg_tag(labs, dataset_id = "LABS", label = "Laboratory measurements")

cat("Patients:", nrow(pts), "\n")
cat("Labs:    ", nrow(labs_tagged), "\n")

## ----derive-------------------------------------------------------------------
# Adult flag
pts <- lg_derive(pts,
  adult = age >= 18L,
  description = "adult: TRUE if age >= 18 years"
)

# Derive population flags
pts <- lg_derive(pts,
  ENRLFL = ifelse(enrolled, "Y", "N"),
  DOSEFL = ifelse(enrolled & dosed, "Y", "N"),
  description = "ENRLFL: enrolled; DOSEFL: enrolled AND received study treatment"
)

# Join lab measurements
pts_labs <- lg_join(pts, labs_tagged,
  by          = "USUBJID",
  type        = "left",
  description = "Merge baseline and endpoint lab measurements from LABS"
)

# Derive analysis variables
analysis_ds <- lg_derive(pts_labs,
  CHG = endpoint - baseline,
  PCHG = round((endpoint - baseline) / baseline * 100, 2),
  description = paste(
    "CHG: absolute change from baseline (endpoint - baseline);",
    "PCHG: percent change from baseline"
  )
)

# Filter to enrolled, adult, dosed patients with complete endpoint
final <- analysis_ds |>
  lg_filter(enrolled == TRUE, adult == TRUE,
    reason      = "Not enrolled or under 18",
    reason_code = "NOT_ENROLLED"
  ) |>
  lg_filter(dosed == TRUE,
    reason      = "Did not receive study treatment",
    reason_code = "NOT_DOSED",
    population  = "SAFETY_SET"
  ) |>
  lg_filter(!is.na(endpoint),
    reason      = "Missing primary endpoint measurement",
    reason_code = "MISSING_EP",
    population  = "ANALYSIS_SET"
  )

cat("Final analysis set:", nrow(final), "patients\n")

## ----population-basic---------------------------------------------------------
lg_population(pts,
  flag_var      = "ENRLFL",
  label         = "Enrolled Set",
  definition    = "All patients who met eligibility criteria and were enrolled in the study",
  incl_criteria = "enrolled == TRUE AND age >= 18"
)

## ----population-multiple------------------------------------------------------
lg_population(pts,
  flag_var      = "DOSEFL",
  label         = "Safety Set",
  definition    = "All enrolled patients who received at least one dose of study treatment",
  incl_criteria = c("enrolled == TRUE", "dosed == TRUE"),
  excl_criteria = "Enrolled but did not receive study treatment (dosed == FALSE)"
)

## ----population-inspect-------------------------------------------------------
env <- getFromNamespace(".lg", "lineager")
pop <- env$populations[["DOSEFL"]]
cat("Flag:       ", pop$flag_var, "\n")
cat("Label:      ", pop$label, "\n")
cat("N included: ", pop$n_included, "\n")
cat("N excluded: ", pop$n_excluded, "\n")
cat("N total:    ", pop$n_total, "\n")

## ----population-print---------------------------------------------------------
print(pop)

## ----spec-basic---------------------------------------------------------------
lg_spec(
  adam_dataset  = "ANALYSIS",
  adam_var      = "CHG",
  label         = "Change from Baseline",
  source_domain = "LABS",
  source_var    = "endpoint / baseline",
  derivation    = "endpoint - baseline; NA when endpoint is missing"
)

lg_spec(
  adam_dataset  = "ANALYSIS",
  adam_var      = "PCHG",
  label         = "Percent Change from Baseline",
  source_domain = "LABS",
  source_var    = "endpoint / baseline",
  derivation    = "(endpoint - baseline) / baseline * 100, rounded to 2 decimal places",
  conditions    = "Only computed when baseline is non-missing and non-zero"
)

## ----spec-flags---------------------------------------------------------------
lg_spec(
  adam_dataset  = "PATIENTS",
  adam_var      = "ENRLFL",
  label         = "Enrolled Flag",
  source_domain = "PATIENTS",
  source_var    = "enrolled",
  derivation    = "Y if enrolled == TRUE; N otherwise"
)

lg_spec(
  adam_dataset  = "PATIENTS",
  adam_var      = "DOSEFL",
  label         = "Safety Flag",
  source_domain = "PATIENTS",
  source_var    = "enrolled / dosed",
  derivation    = "Y if enrolled == TRUE AND dosed == TRUE; N otherwise"
)

## ----spec-overwrite-----------------------------------------------------------
# Refine the CHG derivation description
lg_spec(
  adam_dataset  = "ANALYSIS",
  adam_var      = "CHG",
  label         = "Change from Baseline",
  source_domain = "LABS",
  source_var    = "endpoint / baseline",
  derivation    = "endpoint - baseline. LOCF applied when endpoint missing at Week 12 only.",
  conditions    = "LOCF from Week 8 visit applied per SAP section 7.2"
)

## ----report-memory------------------------------------------------------------
html <- lg_report(
  output   = NULL,
  title    = "Data Provenance Report",
  study_id = "TRIAL-001",
  author   = "Ndoh Penn"
)

cat("Report size:", nchar(html), "characters\n")
cat("Sections found:\n")
sections <- c(
  "Dataset Inventory", "Subject Disposition",
  "Population Flag", "Variable Derivation",
  "Operation Log", "Exclusion Listing"
)
for (s in sections) {
  cat(
    " ", if (grepl(s, html, ignore.case = TRUE)) "[YES]" else "[NO]",
    s, "\n"
  )
}

## ----report-file, eval = FALSE------------------------------------------------
# lg_report(
#   output   = "outputs/provenance_TRIAL001_primary.html",
#   title    = "Data Provenance Report — TRIAL-001 Primary Analysis",
#   study_id = "TRIAL-001",
#   sponsor  = "Example Pharma Ltd",
#   author   = "Ndoh Penn, Biostatistician",
#   date     = as.Date("2026-06-23")
# )

## ----lineage------------------------------------------------------------------
lin <- lg_lineage()
print(lin)

## ----lineage-plot, eval = FALSE-----------------------------------------------
# # Render inline (requires DiagrammeR)
# lg_plot(lin)
# 
# # Export DOT for Graphviz or https://dreampuf.github.io/GraphvizOnline/
# lg_plot(lin, output = "outputs/pipeline.dot")

## ----end----------------------------------------------------------------------
lg_end()

