Skip to contents

Margot package logo showing the package name

margot

MARGinal Observational Treatment-effects.1

The goal of margot is to enhance understanding of causality in observational research. We do this by:

  1. Stating a clear causal question, specifying the intervention(s) to be contrasted, the outcome, the relative timing of interventions and outcomes, potential confounders, and the target population. We call this targeted quantity our causal estimand.

  2. Considering obstacles to identifying our causal estimand from data. This involves asking whether findings from the baseline sample can transport to the target population, and whether selection processes introduce further distortion. It involves checking the three fundamental assumptions for causal inference: consistency, exchangeability, and positivity. It also involves identifying, and where relevant adjusting for, systematic measurement error biases beyond those arising from selection and assumption failures. It finally involves stating quantitative sensitivity and measurement bias analyses. Ideally steps 1 and 2 are completed before any data are collected, but investigators rarely have such luxury.

  3. Defining the statistical estimator, or the method for estimating the targeted causal questions from data.

  4. Performing data analysis, interpreting results, and conveying these results to interested audiences.

Although steps 1-3 are routinely skipped in social scientific research, they are indispensable. Without them, we have no way of assigning meaning to the statistical relationships we observe from data.

Installation

margot is currently available only on GitHub. Install it with pak:

# install.packages("pak")
pak::pak("go-bayes/margot")

If you prefer remotes, use:

# install.packages("remotes")
remotes::install_github("go-bayes/margot")

margot streamlines the estimation of marginal treatment effects such as the ATE and ATT. It also supports workflows for heterogeneous treatment effects using grf, and longitudinal modified treatment policies using lmtp. margot is greatly indebted to the authors of these two excellent packages. margot is best seen as a workflow package for preparing data, evaluating assumptions, estimating causal effects, and communicating results precisely.

Outcome scales in the applied NZAVS workflow

For the New Zealand Attitudes and Values Study (NZAVS), the current applied preparation convention retains continuous baseline and lagged adjustment variables on their unlogged scientific scales before z-standardisation. Terminal outcomes also remain unlogged; for example, exercise is represented by hours_exercise, not log_hours_exercise. Each terminal outcome is standardised once using its unweighted primary-row mean and sample standard deviation, and those constants remain the same across sensitivity analyses and reporting. Analysis weights retain their separate role in estimating the target-population contrast.

Use margot_plot_ate(), margot_table_ate(), and margot_interpret_ate() with saved scale_info to report model-scale estimates and their affine original-unit companions. The outcome-scale guide demonstrates this convention for weekly exercise. General-purpose log and log1p reporting remain available for historical analyses and other questions whose outcomes are explicitly defined on those scales. The preparation convention does not change an existing study’s specification or remove those functions.

Working LMTP fit-once example

Margot includes a complete synthetic perfectionism example with two terminal outcomes and analysis weights. The script locks its execution settings with margot_lmtp_estimator_spec(), fits each policy-specific treatment and censoring density-ratio process once with margot_lmtp(reuse_density_ratios = TRUE), selects the resulting combined table, and passes that table directly to margot_plot(). Its executable assertions require two ratio fits for two policies, compared with four fits under independent outcome-policy estimation.

example_path <- system.file(
  "examples", "lmtp-fit-once-perfectionism.R",
  package = "margot",
  mustWork = TRUE
)
sys.source(example_path, envir = new.env(parent = globalenv()))

Note that Margot is being actively developed, and is not currently in a stable state. Expect breaking changes.