Files
learn-tte/AGENTS.md
T
2026-06-03 22:05:27 -08:00

136 lines
5.9 KiB
Markdown

# Target Trial Emulation Learning Project
This project is for learning how to code and understand target trial emulation in R.
The main teaching example is an ICU septic shock study:
> Among ICU patients with suspected septic shock at ICU admission, what is the effect of initiating vasopressors early versus not initiating vasopressors early on 28-day mortality?
## How To Work With The User
- Teach by showing small code chunks that the user can type in manually.
- Explain each meaningful line of code before moving on.
- Add generous learner-focused comments, especially around R functions, function arguments, return values, and unfamiliar package functions.
- Include many small examples and REPL-style checkpoints with code, expected output, and interpretation.
- Keep report-style Quarto notebooks focused on rendered tables and interpretation unless the user asks for REPL-style checkpoints there.
- Teach the base R mechanics when a concept is new, then prefer readable tidyverse-style code for routine analysis.
- Make the smallest correct change when editing project files.
- Keep scripts and notebooks numbered so the learning sequence is obvious.
- Avoid over-abstraction early; build reusable primitives only after the concept is clear.
- When adding reusable code, explain what future project need it supports.
- When using external dependencies, prefer wrapping them behind project functions so the user learns stable primitives.
## Code Style
- Use the native pipe `|>`, not `%>%`
- snake_case for all names
- Prefer explicit, teaching-oriented comments over terse production-style code while this remains a learning project.
- For reusable functions, include comments describing purpose, arguments, return value, and at least one example call.
- Prefer `vapply` over `sapply`; explicit return types
- Use `cli::cli_*` for messages, not `message()`/`cat()`
- Prefer cleaner imports with grouped startup message suppression, for example `suppressPackageStartupMessages({ library(readr); library(dplyr) })`.
- Prefer `dplyr` verbs for data manipulation when external dependencies are allowed.
- Prefer `skimr` for quick data summaries.
- Prefer `gt` and `gtsummary` for clear analytic tables in notebooks and reports.
- Style with `styler::style_pkg()` before commits
## Don'ts
- Don't modify `renv.lock` by hand
- Don't `setwd()` — rely on the project root (`here::here()`)
- Don't introduce new dependencies beyond the approved stack without asking
## Stack
- R 4.4 managed by rig
- renv for dependency management; lockfile is source of truth
- targets for pipeline orchestration
- tidyverse, especially `dplyr`, for routine data manipulation
- ggplot2 for exploratory plots and visual diagnostics
- data.table for performance-oriented data manipulation when needed
- skimr for quick data summaries
- gt for presentation tables
- gtsummary for descriptive and model summary tables
- Quarto for reports
## Dependency Preference
- The first scripts may remain base R to teach the underlying mechanics.
- Going forward, use `dplyr`, `tidyverse`, `skimr`, `gt`, and `gtsummary` where they make the code clearer.
- Keep base R explanations available when they help the user understand what the package code is doing.
- Do not add packages outside the approved stack without asking first.
## Workflow Roles
- Put reusable logic in `R/` functions.
- Put reusable smoke checks or command-line workflows in `scripts/`.
- Put polished displays, interpretation, exploratory visualization, and rendered result tables in Quarto notebooks.
- Avoid CSV intermediates when functions can be called directly and reproducibly.
- Use `run_all.sh` as the lightweight end-to-end runner until the project is ready for `targets`.
- Keep rendered notebook reports in `outputs/reports/`.
## Learning Roadmap
- [x] Choose ICU teaching scenario: early vasopressor strategy in septic shock.
- [x] Simulate a simple ICU observational cohort.
- [x] Define the target trial protocol explicitly.
- [x] Estimate a naive observational association.
- [ ] Show why naive comparison can be biased.
- [ ] Align time zero and eligibility criteria.
- [ ] Introduce treatment assignment windows.
- [ ] Add censoring logic.
- [ ] Add inverse probability weighting from first principles.
- [x] Refactor repeated logic into reusable project functions.
- [ ] Re-implement selected steps with external dependencies.
- [ ] Build wrapper functions around external dependency workflows.
- [ ] Add a targets pipeline.
- [x] Add initial Quarto report for reproducible analysis.
## Initial Target Trial Protocol
Clinical question:
Among ICU patients with suspected septic shock at ICU admission, what is the effect of starting vasopressors within 2 hours compared with not starting vasopressors within 2 hours on 28-day mortality?
Eligibility criteria:
- ICU admission.
- Suspected sepsis.
- Hypotension at baseline.
- Elevated lactate at baseline.
Time zero:
- ICU admission.
Treatment strategies:
- Early vasopressor strategy: start vasopressors within 2 hours of ICU admission.
- No early vasopressor strategy: do not start vasopressors within 2 hours of ICU admission.
Outcome:
- Death within 28 days.
Baseline confounders in the first simulated dataset:
- Age.
- Sex.
- SOFA score.
- Lactate.
- Mean arterial pressure.
Initial estimand:
- Risk difference in 28-day mortality.
- Risk ratio for 28-day mortality.
## File Sequence
- `run_all.sh`: run the key scripts and render all current notebooks.
- `scripts/01_simulate_icu_data.R`: simulate an ICU cohort in memory and print a quick `skimr` summary.
- `R/simulate_icu_cohort.R`: first reusable simulation primitive.
- `R/estimate_naive_vasopressor_mortality_effect.R`: shared naive mortality-effect primitive used by notebook workflows.
- `notebooks/01_target_trial_basics.qmd`: report-style walkthrough of the target trial protocol and initial results.
- `notebooks/02_explore_simulated_data.qmd`: exploratory visual diagnostics for the simulated cohort.