Learn R Programming

whatifbandit

Overview

whatifbandit is a package designed to answer: "What if my experiment was a bandit trial?"

Using data from the original trial and the user-specified options, it resimulates a randomized controlled trial as an adaptive experiment. Augmented Inverse Probability Weighted estimation (AIPW) is used, following the work of Hadad et. al (2021), to robustly estimate the probability of success under the adaptive experiment.

Adaptive experimental designs, instead of randomly assigning treatments, take into account the relative performance of each treatment. Usually, this means that better-performing treatments will be assigned more participants at each assignment period, allowing for a convergence to the best treatment arm. These designs can shine in situations such as:

  • Simple random assignment produces sample sizes too small to detect treatment effects.
  • A researcher wants to test many treatments, such as 10, 20, or 100.
  • An experiment occurs over a long time, and a researcher wants prior results to impact future assignments.
  • Finding the absolute best treatment takes precedence over gauging the effects of all treatments.

This package allows researchers to showcase how their experiment could have turned out using adaptive assignment, without having the go through the process of running another one. This can unlock new insights in older studies and justify the future usage of adaptive techniques.

Adaptive experiments are a Multi-Arm Bandit Problem, as each treatment arm has an unknown probability of success, and we are forced to assign new participants/observations based on the outcomes already occurred, while balancing the trade-off that comes with exploring each arm, and exploiting the current best arm.

These ideas is what gives the package its name, whatifbandit. bandit for Multi-Arm-Bandit, and whatif for the central question that the package answers.

Features

Whatifbandit provides robust customization options to match as many experimental designs as possible, but it is only equipped to handle experiments where success is binary. Functionality for other cases may be introduced in future development. These major features include:

  • 2 bandit algorithms: probability matching via Thompson sampling, and UCB1.
  • Variable length and flexible assignment periods, such as individual, batch, and date-based.
  • Simulation of perfect and imperfect information during re-assignment.
  • Treatment blocking.
  • Control augmented and hybrid assignments.
  • Variable length information period for re-assignment.

Additionally, whatifbandit supports parallel processing over multiple simulations via future, large data support through data.table, and a full suite of generic functions to accelerate post-simulation analysis.

Installation

# Install From CRAN
install.packages("whatifbandit")

# Install most recent version from GitHub
remotes::install_github("Noch05/whatifbandit")

Usage

Running 1 Trial

sim <- single_mab_simulation(
  data = tanf,
  assignment_method = "Batch",
  period_length = 1000,
  algorithm = "UCB1",
  whole_experiment = TRUE, 
  perfect_assignment = TRUE,
  prior_periods = "All",
  blocking = FALSE,
  data_cols = c(
    id_col = "ic_case_id",
    success_col = "success",
    condition_col = "condition"
  )
)

Running multiple trials.

# Setting seed for Reproducible RNG for the simulation seeds
set.seed(532454)
seeds <- sample.int(1000000, 100, replace = FALSE) 

multiple_sims <- multiple_mab_simulation(
    data = tanf,
    assignment_method = "Date",
    time_unit = "Month",
    period_length = 1,
    algorithm = "Thompson",
    whole_experiment = FALSE, 
    perfect_assignment = TRUE,
    prior_periods = "All",
    blocking = TRUE, 
    block_cols = c("service_center"),
    data_cols = c(
      id_col = "ic_case_id",
      date_col = "appt_date",
      success_col = "success",
      condition_col = "condition",
      month_col = "recert_month",
      success_date_col = "date_of_recert",
      assignment_date_col = "letter_sent_date"
    ),
    keep_data = TRUE, times = 100, seeds = seeds
  )

Running in Multiple Trials in Parallel

future::plan("multisession", workers = availableCores()) # Choose an appropriate plan, and core count for your system

# Setting seed for Reproducible RNG for the simulation seeds
set.seed(532454)
seeds <- sample.int(1000000, 100, replace = FALSE) 


multiple_sims <- multiple_mab_simulation(
    data = tanf,
    assignment_method = "Date",
    time_unit = "Month",
    period_length = 1,
    algorithm = "Thompson",
    whole_experiment = FALSE, 
    perfect_assignment = TRUE,
    prior_periods = "All",
    blocking = TRUE, 
    block_cols = c("service_center"),
    data_cols = c(
      id_col = "ic_case_id",
      date_col = "appt_date",
      success_col = "success",
      condition_col = "condition",
      month_col = "recert_month",
      success_date_col = "date_of_recert",
      assignment_date_col = "letter_sent_date"
    ),
    keep_data = TRUE, times = 100, seeds = seeds
  )
future::plan("sequential")

More Information

For more complete information about the package details, please refer to the vignette tutorial and the full documentation.

If you have any specific questions about the package, feel free to send me an email at noahochital@icloud.com, and if you encounter any bugs, please create an issue on GitHub with a reproducible example.

Copy Link

Version

Install

install.packages('whatifbandit')

Monthly Downloads

201

Version

0.3.0

License

GPL (>= 3)

Issues

Pull Requests

Stars

Forks

Maintainer

Noah Ochital

Last Published

November 3rd, 2025

Functions in whatifbandit (0.3.0)

create_conditions

Creating proper conditions vector
check_prop

Checking for Proportions
condense_results

Condenses results into a list for multiple_mab_simulation()
cols

Column arguments shared across functions
create_new_cols

Create Necessary Columns for Multi-Arm Bandit Trial
imputation_preparation

Outcome Imputation Preparation
mab_simulation

Simulates Multi-Arm Bandit Trial From Prepared Inputs
create_cutoff

Create Treatment Wave Cutoffs
imputation_precompute

Precomputing Key Values for Outcome Imputation
impute_success

Imputing New Outcomes of Multi-Arm-Bandit Trial
get_bandit

Calculate Multi-Arm Bandit Decision Based on Algorithm
plot.mab

Plot Generic for mab objects
multiple_mab_simulation

Run Multiple Multi-Arm-Bandit Trials with Inference in Parallel
end_mab_trial

Ends Multi-Arm Bandit Trial
get_past_results

Gather Past Results for Given Assignment Period
get_assignment_quantitites

Calculates Number of Observations Assigned to Each Treatment
get_iaipw

Calculate Observation Level AIPW For Each Treatment Condition
get_bandit.thompson

Thompson sampling Algorithm
get_bandit.ucb1

UCB1 Sampling Algorithm
print.mab

Print Generic For mab
plot.multiple.mab

Plot Generic For multiple.mab Objects
plot_mult_estimates

Plots AIPW Confidence Intervals
plot_hist

Plots Histograms of multiple_mab_simulation() Results
print.multiple.mab

Print Generic For multiple.mab
plot_arms

Plot Treatment Arms Over Time
plot_assign

Plot Cumulative Assignment Probability Over Time
plot_estimates

Plot AIPW Estimates
print_mab

Print Helper for mab and multiple.mab
summary.multiple.mab

Summary Generic For "multiple.mab" Class
tanf

Public TANF Recipient Data From Washington D.C
plot_summary

Plot Treatment Arms Over Multiple Trials
whatifbandit-package

whatifbandit: Analyzing Randomized Experiments as Multi-Arm Bandits
pre_mab_simulation

Pre-Simulation Setup for an adaptive Multi-Arm-Bandit Trial
run_mab_trial

Runs Multi-Arm Bandit Trial
validate_inputs

Validates Inputs For single_mab_simulation() and multiple_mab_simulation()
verbose_log

Verbose Printer
summary.mab

Summary Generic For "mab" Class
single_mab_simulation

Run One Adaptive Simulation With Inference.
check_impute

Checking Imputation Info
check_level

Check Level
create_prior

Create Prior Periods
assign_treatments

Adaptively Assign Treatments in a Period
bandit_invalid

Checks Validity of Thompson sampling probabilities
adaptive_aipw

Calculate Adaptive AIPW Estimates
check_cols

Checking existence and declaration of columns
check_assign_method

Checking For Valid Assignment Methods
check_data

Checking for Valid Input Data
check_logical

Checking if Inputs are Logical Values (TRUE and FALSE)
check_posint

Checking If Inputs Are Positive Integers or a Valid String