---
title: "Get started"
vignette: >
  %\VignetteIndexEntry{Get Started}
  %\VignetteEngine{quarto::html}
  %\VignetteEncoding{UTF-8}
knitr:
  opts_chunk:
    collapse: true
    comment: '#>'
---

```{r}
#| include: false
# `mighty.component` fetches component templates from GitHub via the
# `gh` package. `gh` < 1.6.0 rejects the `ghs_` App-installation token
# that CI provides, so we skip evaluation on runners pinned to an
# older CRAN snapshot.
knitr::opts_chunk$set(
  eval = utils::packageVersion("gh") >= "1.6.0" ||
    isFALSE(as.logical(Sys.getenv("CI", "false")))
)
```

```{r}
#| include: false
library(mighty)

# Create study directory structure
study_dir <- file.path(tempdir(), "mighty_example_study")
dir.create(study_dir, showWarnings = FALSE, recursive = TRUE)
assign("study_dir", study_dir, envir = .GlobalEnv)

# Custom components live outside the specifications directory
components_dir <- file.path(tempdir(), "mighty_example_components")
dir.create(components_dir, showWarnings = FALSE, recursive = TRUE)


# Create _study.yml with study-level properties
writeLines("study_id: example_study", file.path(study_dir, "_study.yml"))

# Create _mighty.yml with external data specifications
mighty_yaml <- 'external_data:
  - id: DM
    keys: [USUBJID, STUDYID]
  - id: LB
    keys: [USUBJID, STUDYID, LBSEQ]
repos:
  - "github::NovoNordisk-OpenSource/mighty.standards/components@dev/internal-components"
  - "./components"
'
# The components repo needs to be an absolute path when the vignette is
# rendered by `pkgdown`, but we don't want to show that ugly tmp path to the
# users
mighty_yaml_with_abspath <- gsub(
  '"./components"',
  sprintf('"%s"', normalizePath(components_dir, winslash = "/")),
  mighty_yaml,
  fixed = TRUE
)
writeLines(mighty_yaml_with_abspath, file.path(study_dir, "_mighty.yml"))
assign("mighty_yaml", mighty_yaml, envir = .GlobalEnv)


# Create ADSL domain specification
adsl_yaml <- 'id: ADSL
label: Subject Level Analysis Dataset
class: SUBJECT LEVEL ANALYSIS DATASET
structure: One record per subject
keys: [USUBJID, STUDYID]

population:
  base:
    - domain: DM
      depends:
        - AGE
      filter: \'!is.na(AGE)\'
  global:
    - filter: NA
      depends:
        - NA

columns:
  - id: USUBJID

  - id: STUDYID

  - id: ARM

  - id: PLANNED_ARM
    method: ADSL.ARM

  - id: AGE

  - id: AGE_GRP1
    component:
      id: "age_group_01.R"
'
writeLines(adsl_yaml, file.path(study_dir, "adsl.yml"))
assign("adsl_yaml", adsl_yaml, envir = .GlobalEnv)


component_code <- "#' @title Age group 01
#' @description Grouping of age
#' @type column
#' @origin Derived
#' @method Age cut into the groups < 18, 18-64, 65-74 and >= 75 years.
#' @depends ADSL AGE
#' @outputs AGE_GRP1
#' @returns `ADSL`
#' @code
ADSL <- ADSL |>
  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
    )
  )
"
writeLines(component_code, file.path(components_dir, "age_group_01.R"))
assign("component_code", component_code, envir = .GlobalEnv)


main_script_content <- "# ADSL with 1 base domain
#   - 4 predecessors
#   - 1 renamed predecessor
#   - 1 derivation

# Load mighty
library(mighty)

# Generate ADaM program
results <- mighty::generate_adam_code(
  adam_specifications = \"study_dir\",
  path_connector_config = \"_connector.yml\"
)

# Print rendered ADaM program
results$programs$`1_ADSL` |> cat()
"
writeLines(main_script_content, file.path(study_dir, "example_01_main.R"))
assign("main_script_content", main_script_content, envir = .GlobalEnv)
```

# Your first mighty ADaM program

Here is a minimal example that demonstrates how to specify and render a simple ADSL program with mighty to get you acquainted with the core concepts of the framework.

## Study directory guidelines

The only constraints mighty has on the directory structure is the presence of a directory that contains **only** the following YAML specification files:

- Domain specifications (e.g., `adsl.yml`, `adae.yml`, `adlb.yml`)
- `_mighty.yml` — [framework configuration](mighty_config.qmd) (external dataset keys and component repos)
- `_study.yml` — study-level properties (optional, used by mighty.toolbox for define.xml)


All `.yml`/`.yaml` files in this directory (except `_mighty.yml` and `_study.yml`) are parsed as domain specifications. Placing non-specification YAML files (such as a connector config) in the specifications directory will cause validation errors.

Other files should live outside the specifications directory:

- A [connector config file](https://novonordisk-opensource.github.io/connector/) that specifies where your trial data is located (SDTM, metadata, and ADaM). The `path_connector_config` argument to `generate_adam_code()` is the file path to the connector config file, embedded verbatim into the generated programs.
- Study-specific custom components
- A location where the compiled ADaM programs can be written out to

## Set up your framework configuration file

The `_mighty.yml` file provides framework configuration that spans across all ADaM domains.
This includes primary keys for external datasets that are used for joining tables.

For this example, we will focus on a simple ADSL table and only provide keys related to that domain.

The `repos` field lists where mighty looks for code components. The first entry points to the standard components repo; the second is a local directory with the study-specific custom components.

**\_mighty.yml**

```{r}
#| echo: false
#| results: asis
cat("```yml\n")
cat(mighty_yaml)
cat("```")
```

## Set up your ADaM specification

Provide a YAML file that specifies which columns to include in ADSL and how they are derived. The specification **only contains columns that belong in the final dataset**; source columns needed only during derivation are handled through component dependencies instead. See `vignette("adam_specification")` for details.

This ADSL table contains 6 columns: 4 simple columns from the base domain, 1 renamed column, and 1 derivation using a custom component.

**adsl.yml**

```{r}
#| echo: false
#| results: asis
cat("```yml\n")
cat(adsl_yaml)
cat("```")
```

## Define your custom component

The column `AGE_GRP1` in ADSL is derived by using a custom component that contains the logic to process the ADSL table by deriving the additional column `AGE_GRP1`.

Save the component in the `components` directory listed under `repos`. The ADaM specification refers to it by its file name, `age_group_01.R`.

Relative paths in `repos` are resolved against the working directory, not against the location of `_mighty.yml`. This example assumes R is started in the folder that contains both `study_dir/` and `components/`:

```
my_study/                 <- working directory when running example_01_main.R
├── example_01_main.R
├── _connector.yml
├── study_dir/            <- adam_specifications
│   ├── _mighty.yml
│   ├── _study.yml
│   └── adsl.yml
└── components/           <- "./components" in repos
    └── age_group_01.R
```

**age_group_01.R**

```{r}
#| echo: false
#| results: asis
cat("```r\n")
cat(component_code)
cat("```")
```

## Render the ADaM program

Call mighty to consolidate, analyze and render your ADSL program:

**example_01_main.R**

```{r}
#| echo: false
#| results: asis
cat("```r\n")
cat(main_script_content)
cat("\n```")
```

Printing the rendered ADaM program yields a complete program for generating ADSL based on the specifications

```{r}
#| echo: false
#| results: asis
# Execute the code generation
results <- mighty::generate_adam_code(
  adam_specifications = study_dir,
  path_connector_config = file.path(study_dir, "_connector.yml")
)

# Display the generated program with R formatting
cat("```r\n")
cat(results$programs$`1_ADSL`)
cat("\n```")
```
