Title: | Non-Parametric Causal Effects of Feasible Interventions Based on Modified Treatment Policies |
---|---|
Description: | Non-parametric estimators for casual effects based on longitudinal modified treatment policies as described in Diaz, Williams, Hoffman, and Schenck <doi:10.1080/01621459.2021.1955691>, traditional point treatment, and traditional longitudinal effects. Continuous, binary, categorical treatments, and multivariate treatments are allowed as well are censored outcomes. The treatment mechanism is estimated via a density ratio classification procedure irrespective of treatment variable type. For both continuous and binary outcomes, additive treatment effects can be calculated and relative risks and odds ratios may be calculated for binary outcomes. Supports survival outcomes with competing risks (Diaz, Hoffman, and Hejazi; <doi:10.1007/s10985-023-09606-7>). |
Authors: | Nicholas Williams [aut, cre, cph]
|
Maintainer: | Nicholas Williams <[email protected]> |
License: | AGPL-3 |
Version: | 1.5.0 |
Built: | 2025-03-07 20:25:32 UTC |
Source: | https://github.com/nt-williams/lmtp |
Creates a node list specification that is used by the provided estimators.
create_node_list()
is not explicitly called by the analyst, rather
it is provided so the analyst can confirm how estimators will use variables
before actually performing the estimation procedure.
create_node_list(trt, tau, time_vary = NULL, baseline = NULL, k = Inf)
create_node_list(trt, tau, time_vary = NULL, baseline = NULL, k = Inf)
trt |
A vector of column names of treatment variables. |
tau |
The number of time points of observation, excluding the final outcome. |
time_vary |
A list of length tau with the column names for new time_vary to be introduced at each time point. The list should be ordered following the time ordering of the model. |
baseline |
An optional vector of columns names for baseline covariates to be included for adjustment at every timepoint. |
k |
An integer specifying how previous time points should be
used for estimation at the given time point. Default is |
A list of lists. Each sub-list is the same length of the
time_vary
parameter with the variables to be used for estimation at that given time point
for either the treatment mechanism or outcome regression.
## Not run: a <- c("A_1", "A_2", "A_3", "A_4") bs <- c("W_1", "W_2") time_vary <- list(c("L_1"), c("L_2"), c("L_3"), c("L_4")) # assuming no Markov property create_node_list(a, 4, time_vary, bs, k = Inf) ## End(Not run)
## Not run: a <- c("A_1", "A_2", "A_3", "A_4") bs <- c("W_1", "W_2") time_vary <- list(c("L_1"), c("L_2"), c("L_3"), c("L_4")) # assuming no Markov property create_node_list(a, 4, time_vary, bs, k = Inf) ## End(Not run)
A helper function to prepare survival data for use with LMTP estimators by imputing outcome nodes using last outcome carried forward when an observation experiences the event before the end-of-follow-up.
event_locf(data, outcomes)
event_locf(data, outcomes)
data |
The dataset to modify. |
outcomes |
A vector of outcome nodes ordered by time. |
A modified dataset with future outcome nodes set to 1 if an observation experienced an event at any previous time point.
event_locf(sim_point_surv, paste0("Y.", 1:6))
event_locf(sim_point_surv, paste0("Y.", 1:6))
A function factory that returns a shift function for increasing or decreasing the probability of exposure when exposure is binary.
ipsi(delta)
ipsi(delta)
delta |
[ |
A shift function.
data("iptwExWide", package = "twang") a <- paste0("tx", 1:3) baseline <- c("gender", "age") tv <- list(c("use0"), c("use1"), c("use2")) lmtp_sdr(iptwExWide, a, "outcome", baseline = baseline, time_vary = tv, shift = ipsi(0.5), outcome_type = "continuous", folds = 2)
data("iptwExWide", package = "twang") a <- paste0("tx", 1:3) baseline <- c("gender", "age") tv <- list(c("use0"), c("use1"), c("use2")) lmtp_sdr(iptwExWide, a, "outcome", baseline = baseline, time_vary = tv, shift = ipsi(0.5), outcome_type = "continuous", folds = 2)
Estimates contrasts of multiple LMTP fits compared to either a known reference value or a reference LMTP fit.
lmtp_contrast(..., ref, type = c("additive", "rr", "or"))
lmtp_contrast(..., ref, type = c("additive", "rr", "or"))
... |
One or more objects of class lmtp. |
ref |
A reference value or another lmtp fit to compare all other fits against. |
type |
The contrasts of interest. Options are "additive" (the default), "rr", and "or". |
A list of class lmtp_contrast
containing the following components:
type |
The type of contrast performed. |
null |
The null hypothesis. |
estimates |
A dataframe containing the contrasts estimates, standard errors, and confidence intervals. |
a <- c("A1", "A2") nodes <- list(c("L1"), c("L2")) cens <- c("C1", "C2") y <- "Y" # mean population outcome psi_null <- lmtp_tmle(sim_cens, a, y, time_vary = nodes, cens = cens, shift = NULL, folds = 1) # treatment rule, everyone is increased by 0.5 d <- function(data, x) data[[x]] + 0.5 psi_rule1 <- lmtp_tmle(sim_cens, a, y, time_vary = nodes, cens = cens, shift = d, folds = 1, mtp = TRUE) # treatment rule, everyone is decreased by 0.5 d <- function(data, x) data[[x]] - 0.5 psi_rule2 <- lmtp_tmle(sim_cens, a, y, time_vary = nodes, cens = cens, shift = d, folds = 1, mtp = TRUE) # Example 1.1 # Additive effect of rule 1 compared to a known constant lmtp_contrast(psi_rule1, ref = 0.9) # Example 1.2 # Additive effect of rule 1 compared to the population mean outcome lmtp_contrast(psi_rule1, ref = psi_null) # Example 1.3 # Additive effects of rule 1 and 2 compared to the population mean outcome lmtp_contrast(psi_rule1, psi_rule2, ref = psi_null) # Example 1.4 # Relative risk of rule 1 compared to observed exposure lmtp_contrast(psi_rule1, ref = psi_null, type = "rr") # Example 1.5 # Odds of rule 1 compared to observed exposure lmtp_contrast(psi_rule1, ref = psi_null, type = "or")
a <- c("A1", "A2") nodes <- list(c("L1"), c("L2")) cens <- c("C1", "C2") y <- "Y" # mean population outcome psi_null <- lmtp_tmle(sim_cens, a, y, time_vary = nodes, cens = cens, shift = NULL, folds = 1) # treatment rule, everyone is increased by 0.5 d <- function(data, x) data[[x]] + 0.5 psi_rule1 <- lmtp_tmle(sim_cens, a, y, time_vary = nodes, cens = cens, shift = d, folds = 1, mtp = TRUE) # treatment rule, everyone is decreased by 0.5 d <- function(data, x) data[[x]] - 0.5 psi_rule2 <- lmtp_tmle(sim_cens, a, y, time_vary = nodes, cens = cens, shift = d, folds = 1, mtp = TRUE) # Example 1.1 # Additive effect of rule 1 compared to a known constant lmtp_contrast(psi_rule1, ref = 0.9) # Example 1.2 # Additive effect of rule 1 compared to the population mean outcome lmtp_contrast(psi_rule1, ref = psi_null) # Example 1.3 # Additive effects of rule 1 and 2 compared to the population mean outcome lmtp_contrast(psi_rule1, psi_rule2, ref = psi_null) # Example 1.4 # Relative risk of rule 1 compared to observed exposure lmtp_contrast(psi_rule1, ref = psi_null, type = "rr") # Example 1.5 # Odds of rule 1 compared to observed exposure lmtp_contrast(psi_rule1, ref = psi_null, type = "or")
Set LMTP Estimation Parameters
lmtp_control( .bound = 1e+05, .trim = 0.999, .learners_outcome_folds = 10, .learners_trt_folds = 10, .return_full_fits = FALSE, .discrete = TRUE, .info = FALSE )
lmtp_control( .bound = 1e+05, .trim = 0.999, .learners_outcome_folds = 10, .learners_trt_folds = 10, .return_full_fits = FALSE, .discrete = TRUE, .info = FALSE )
.bound |
[ |
.trim |
[ |
.learners_outcome_folds |
[ |
.learners_trt_folds |
[ |
.return_full_fits |
[ |
.discrete |
[ |
.info |
[ |
A list of parameters controlling the estimation procedure.
lmtp_control(.trim = 0.975)
lmtp_control(.trim = 0.975)
Sequentially doubly robust estimator for the effects of traditional causal effects and modified treatment policies for both point treatment and longitudinal data with binary, continuous, or time-to-event outcomes. Supports binary, categorical, and continuous exposures.
lmtp_sdr( data, trt, outcome, baseline = NULL, time_vary = NULL, cens = NULL, compete = NULL, shift = NULL, shifted = NULL, k = Inf, mtp = FALSE, outcome_type = c("binomial", "continuous", "survival"), id = NULL, bounds = NULL, learners_outcome = "SL.glm", learners_trt = "SL.glm", folds = 10, weights = NULL, control = lmtp_control() )
lmtp_sdr( data, trt, outcome, baseline = NULL, time_vary = NULL, cens = NULL, compete = NULL, shift = NULL, shifted = NULL, k = Inf, mtp = FALSE, outcome_type = c("binomial", "continuous", "survival"), id = NULL, bounds = NULL, learners_outcome = "SL.glm", learners_trt = "SL.glm", folds = 10, weights = NULL, control = lmtp_control() )
data |
[ |
trt |
[ |
outcome |
[ |
baseline |
[ |
time_vary |
[ |
cens |
[ |
compete |
[ |
shift |
[ |
shifted |
[ |
k |
[ |
mtp |
[ |
outcome_type |
[ |
id |
[ |
bounds |
[ |
learners_outcome |
[ |
learners_trt |
[ |
folds |
[ |
weights |
[ |
control |
[ |
mtp = TRUE
?A modified treatment policy (MTP) is an intervention that depends
on the natural value of the exposure (the value that the treatment would have taken under no intervention).
This differs from other causal effects,
such as the average treatment effect (ATE), where an exposure would be increased (or decreased) deterministically.
If your intervention of interest adds, subtracts, or multiplies the observed treatment values
by some amount, use mtp = TRUE
.
A list of class lmtp
containing the following components:
estimator |
The estimator used, in this case "SDR". |
estimates |
The estimated population LMTP effect as an |
shift |
The shift function specifying the treatment policy of interest. |
outcome_reg |
An n x Tau + 1 matrix of outcome regression predictions. The mean of the first column is used for calculating theta. |
density_ratios |
An n x Tau matrix of the estimated, non-cumulative, density ratios. |
fits_m |
A list the same length as |
fits_r |
A list the same length as |
outcome_type |
The outcome variable type. |
set.seed(56) n <- 1000 W <- rnorm(n, 10, 5) A <- 23 + 5*W + rnorm(n) Y <- 7.2*A + 3*W + rnorm(n) ex1_dat <- data.frame(W, A, Y) # Example 1.1 # Point treatment, continuous exposure, continuous outcome, no loss-to-follow-up # Interested in the effect of a modified treatment policy where A is decreased by 15 # units only among observations whose observed A was above 80. # The true value under this intervention is about 513. policy <- function(data, x) { (data[[x]] > 80)*(data[[x]] - 15) + (data[[x]] <= 80)*data[[x]] } lmtp_sdr(ex1_dat, "A", "Y", "W", shift = policy, outcome_type = "continuous", folds = 2, mtp = TRUE) # Example 2.1 # Longitudinal setting, time-varying continuous exposure bounded by 0, # time-varying covariates, and a binary outcome with no loss-to-follow-up. # Interested in the effect of a treatment policy where exposure decreases by # one unit at every time point if an observations observed exposure is greater # than or equal to 2. The true value under this intervention is about 0.305. head(sim_t4) A <- c("A_1", "A_2", "A_3", "A_4") L <- list(c("L_1"), c("L_2"), c("L_3"), c("L_4")) policy <- function(data, trt) { a <- data[[trt]] (a - 1) * (a - 1 >= 1) + a * (a - 1 < 1) } # BONUS: progressr progress bars! progressr::handlers(global = TRUE) lmtp_sdr(sim_t4, A, "Y", time_vary = L, shift = policy, folds = 2, mtp = TRUE) # Example 2.2 # The previous example assumed that the outcome (as well as the treatment variables) # were directly affected by all other nodes in the past. In certain situations, # domain specific knowledge may suggest otherwise. # This can be controlled using the k argument. lmtp_sdr(sim_t4, A, "Y", time_vary = L, shift = policy, k = 0, folds = 2, mtp = TRUE) # Example 2.3 # Using the same data as examples 2.1 and 2.2. # Now estimating the effect of a dynamic modified treatment policy. # creating a dynamic mtp that applies the shift function # but also depends on history and the current time policy <- function(data, trt) { mtp <- function(data, trt) { (data[[trt]] - 1) * (data[[trt]] - 1 >= 1) + data[[trt]] * (data[[trt]] - 1 < 1) } # if its the first time point, follow the same mtp as before if (trt == "A_1") return(mtp(data, trt)) # otherwise check if the time varying covariate equals 1 ifelse( data[[sub("A", "L", trt)]] == 1, mtp(data, trt), # if yes continue with the policy data[[trt]] # otherwise do nothing ) } lmtp_sdr(sim_t4, A, "Y", time_vary = L, mtp = TRUE, k = 0, shift = policy, folds = 2) # Example 2.4 # Using the same data as examples 2.1, 2.2, and 2.3, but now treating the exposure # as an ordered categorical variable. To account for the exposure being a # factor we just need to modify the shift function (and the original data) # so as to respect this. tmp <- sim_t4 for (i in A) { tmp[[i]] <- factor(tmp[[i]], levels = 0:5, ordered = FALSE) } policy <- function(data, trt) { out <- list() a <- data[[trt]] for (i in 1:length(a)) { if (as.character(a[i]) %in% c("0", "1")) { out[[i]] <- as.character(a[i]) } else { out[[i]] <- as.numeric(as.character(a[i])) - 1 } } factor(unlist(out), levels = 0:5, ordered = FALSE) } lmtp_sdr(tmp, A, "Y", time_vary = L, shift = policy, k = 0, folds = 2, mtp = TRUE) # Example 3.1 # Longitudinal setting, time-varying binary treatment, time-varying covariates # and baseline covariates with no loss-to-follow-up. Interested in a "traditional" # causal effect where treatment is set to 1 at all time points for all observations. if (require("twang")) { data("iptwExWide", package = "twang") A <- paste0("tx", 1:3) W <- c("gender", "age") L <- list(c("use0"), c("use1"), c("use2")) lmtp_sdr( iptwExWide, A, "outcome", baseline = W, time_vary = L, shift = static_binary_on, outcome_type = "continuous", mtp = FALSE, folds = 2 ) } # Example 4.1 # Longitudinal setting, time-varying continuous treatment, time-varying covariates, # binary outcome with right censoring. Interested in the mean population outcome under # the observed exposures in a hypothetical population with no loss-to-follow-up. head(sim_cens) A <- c("A1", "A2") L <- list(c("L1"), c("L2")) C <- c("C1", "C2") Y <- "Y" lmtp_sdr(sim_cens, A, Y, time_vary = L, cens = C, shift = NULL, folds = 2) # Example 5.1 # Time-to-event analysis with a binary time-invariant exposure. Interested in # the effect of treatment being given to all observations on the cumulative # incidence of the outcome. # For a survival problem, the outcome argument now takes a vector of outcomes # if an observation experiences the event prior to the end of follow-up, all future # outcome nodes should be set to 1 (i.e., last observation carried forward). A <- "trt" Y <- paste0("Y.", 1:6) C <- paste0("C.", 0:5) W <- c("W1", "W2") lmtp_sdr(sim_point_surv, A, Y, W, cens = C, folds = 2, shift = static_binary_on, outcome_type = "survival") # Example 6.1 # Intervening on multiple exposures simultaneously. Interested in the effect of # a modified treatment policy where variable D1 is decreased by 0.1 units and # variable D2 is decreased by 0.5 units simultaneously. A <- list(c("D1", "D2")) W <- paste0("C", 1:3) Y <- "Y" d <- function(data, a) { out = list( data[[a[1]]] - 0.1, data[[a[2]]] - 0.5 ) setNames(out, a) } lmtp_sdr(multivariate_data, A, Y, W, shift = d, outcome_type = "continuous", folds = 1, mtp = TRUE) # Example 7.1 # Time-to-event analysis with a binary time-invariant exposure and a competing-risk. lmtp_sdr( data = sim_competing_risks, trt = "A", cens = paste0("C", 1:5), compete = paste0("D", 1:5), baseline = paste0("W", 1:5), outcome = paste0("Y", 1:5), outcome_type = "survival", shift = static_binary_on, folds = 1 )
set.seed(56) n <- 1000 W <- rnorm(n, 10, 5) A <- 23 + 5*W + rnorm(n) Y <- 7.2*A + 3*W + rnorm(n) ex1_dat <- data.frame(W, A, Y) # Example 1.1 # Point treatment, continuous exposure, continuous outcome, no loss-to-follow-up # Interested in the effect of a modified treatment policy where A is decreased by 15 # units only among observations whose observed A was above 80. # The true value under this intervention is about 513. policy <- function(data, x) { (data[[x]] > 80)*(data[[x]] - 15) + (data[[x]] <= 80)*data[[x]] } lmtp_sdr(ex1_dat, "A", "Y", "W", shift = policy, outcome_type = "continuous", folds = 2, mtp = TRUE) # Example 2.1 # Longitudinal setting, time-varying continuous exposure bounded by 0, # time-varying covariates, and a binary outcome with no loss-to-follow-up. # Interested in the effect of a treatment policy where exposure decreases by # one unit at every time point if an observations observed exposure is greater # than or equal to 2. The true value under this intervention is about 0.305. head(sim_t4) A <- c("A_1", "A_2", "A_3", "A_4") L <- list(c("L_1"), c("L_2"), c("L_3"), c("L_4")) policy <- function(data, trt) { a <- data[[trt]] (a - 1) * (a - 1 >= 1) + a * (a - 1 < 1) } # BONUS: progressr progress bars! progressr::handlers(global = TRUE) lmtp_sdr(sim_t4, A, "Y", time_vary = L, shift = policy, folds = 2, mtp = TRUE) # Example 2.2 # The previous example assumed that the outcome (as well as the treatment variables) # were directly affected by all other nodes in the past. In certain situations, # domain specific knowledge may suggest otherwise. # This can be controlled using the k argument. lmtp_sdr(sim_t4, A, "Y", time_vary = L, shift = policy, k = 0, folds = 2, mtp = TRUE) # Example 2.3 # Using the same data as examples 2.1 and 2.2. # Now estimating the effect of a dynamic modified treatment policy. # creating a dynamic mtp that applies the shift function # but also depends on history and the current time policy <- function(data, trt) { mtp <- function(data, trt) { (data[[trt]] - 1) * (data[[trt]] - 1 >= 1) + data[[trt]] * (data[[trt]] - 1 < 1) } # if its the first time point, follow the same mtp as before if (trt == "A_1") return(mtp(data, trt)) # otherwise check if the time varying covariate equals 1 ifelse( data[[sub("A", "L", trt)]] == 1, mtp(data, trt), # if yes continue with the policy data[[trt]] # otherwise do nothing ) } lmtp_sdr(sim_t4, A, "Y", time_vary = L, mtp = TRUE, k = 0, shift = policy, folds = 2) # Example 2.4 # Using the same data as examples 2.1, 2.2, and 2.3, but now treating the exposure # as an ordered categorical variable. To account for the exposure being a # factor we just need to modify the shift function (and the original data) # so as to respect this. tmp <- sim_t4 for (i in A) { tmp[[i]] <- factor(tmp[[i]], levels = 0:5, ordered = FALSE) } policy <- function(data, trt) { out <- list() a <- data[[trt]] for (i in 1:length(a)) { if (as.character(a[i]) %in% c("0", "1")) { out[[i]] <- as.character(a[i]) } else { out[[i]] <- as.numeric(as.character(a[i])) - 1 } } factor(unlist(out), levels = 0:5, ordered = FALSE) } lmtp_sdr(tmp, A, "Y", time_vary = L, shift = policy, k = 0, folds = 2, mtp = TRUE) # Example 3.1 # Longitudinal setting, time-varying binary treatment, time-varying covariates # and baseline covariates with no loss-to-follow-up. Interested in a "traditional" # causal effect where treatment is set to 1 at all time points for all observations. if (require("twang")) { data("iptwExWide", package = "twang") A <- paste0("tx", 1:3) W <- c("gender", "age") L <- list(c("use0"), c("use1"), c("use2")) lmtp_sdr( iptwExWide, A, "outcome", baseline = W, time_vary = L, shift = static_binary_on, outcome_type = "continuous", mtp = FALSE, folds = 2 ) } # Example 4.1 # Longitudinal setting, time-varying continuous treatment, time-varying covariates, # binary outcome with right censoring. Interested in the mean population outcome under # the observed exposures in a hypothetical population with no loss-to-follow-up. head(sim_cens) A <- c("A1", "A2") L <- list(c("L1"), c("L2")) C <- c("C1", "C2") Y <- "Y" lmtp_sdr(sim_cens, A, Y, time_vary = L, cens = C, shift = NULL, folds = 2) # Example 5.1 # Time-to-event analysis with a binary time-invariant exposure. Interested in # the effect of treatment being given to all observations on the cumulative # incidence of the outcome. # For a survival problem, the outcome argument now takes a vector of outcomes # if an observation experiences the event prior to the end of follow-up, all future # outcome nodes should be set to 1 (i.e., last observation carried forward). A <- "trt" Y <- paste0("Y.", 1:6) C <- paste0("C.", 0:5) W <- c("W1", "W2") lmtp_sdr(sim_point_surv, A, Y, W, cens = C, folds = 2, shift = static_binary_on, outcome_type = "survival") # Example 6.1 # Intervening on multiple exposures simultaneously. Interested in the effect of # a modified treatment policy where variable D1 is decreased by 0.1 units and # variable D2 is decreased by 0.5 units simultaneously. A <- list(c("D1", "D2")) W <- paste0("C", 1:3) Y <- "Y" d <- function(data, a) { out = list( data[[a[1]]] - 0.1, data[[a[2]]] - 0.5 ) setNames(out, a) } lmtp_sdr(multivariate_data, A, Y, W, shift = d, outcome_type = "continuous", folds = 1, mtp = TRUE) # Example 7.1 # Time-to-event analysis with a binary time-invariant exposure and a competing-risk. lmtp_sdr( data = sim_competing_risks, trt = "A", cens = paste0("C", 1:5), compete = paste0("D", 1:5), baseline = paste0("W", 1:5), outcome = paste0("Y", 1:5), outcome_type = "survival", shift = static_binary_on, folds = 1 )
Wrapper around lmtp_tmle
and lmtp_sdr
for survival outcomes to estimate the entire survival curve.
Estimates are reconstructed using isotonic regression to enforce monotonicity of the survival curve.
Confidence intervals correspond to marginal confidence intervals for the survival curve, not simultaneous intervals.
lmtp_survival( data, trt, outcomes, baseline = NULL, time_vary = NULL, cens = NULL, compete = NULL, shift = NULL, shifted = NULL, estimator = c("lmtp_tmle", "lmtp_sdr"), k = Inf, mtp = FALSE, id = NULL, learners_outcome = "SL.glm", learners_trt = "SL.glm", folds = 10, weights = NULL, control = lmtp_control() )
lmtp_survival( data, trt, outcomes, baseline = NULL, time_vary = NULL, cens = NULL, compete = NULL, shift = NULL, shifted = NULL, estimator = c("lmtp_tmle", "lmtp_sdr"), k = Inf, mtp = FALSE, id = NULL, learners_outcome = "SL.glm", learners_trt = "SL.glm", folds = 10, weights = NULL, control = lmtp_control() )
data |
[ |
trt |
[ |
outcomes |
[ |
baseline |
[ |
time_vary |
[ |
cens |
[ |
compete |
[ |
shift |
[ |
shifted |
[ |
estimator |
[ |
k |
[ |
mtp |
[ |
id |
[ |
learners_outcome |
[ |
learners_trt |
[ |
folds |
[ |
weights |
[ |
control |
[ |
A list of class lmtp_survival
containing lmtp
objects for each time point.
# Example 1.1 # Time-to-event analysis with a binary time-invariant exposure. Interested in # the effect of treatment being given to all observations on the cumulative # incidence of the outcome. A <- "trt" Y <- paste0("Y.", 1:6) C <- paste0("C.", 0:5) W <- c("W1", "W2") curve <- lmtp_survival(sim_point_surv, A, Y, W, cens = C, folds = 1, shift = static_binary_on, estimator = "lmtp_tmle") tidy(curve) # Example 1.2 # Time-to-event analysis with a binary time-invariant exposure and a competing-risk. lmtp_survival( data = sim_competing_risks, trt = "A", cens = paste0("C", 1:5), compete = paste0("D", 1:5), baseline = paste0("W", 1:5), outcome = paste0("Y", 1:5), shift = static_binary_on, folds = 1 )
# Example 1.1 # Time-to-event analysis with a binary time-invariant exposure. Interested in # the effect of treatment being given to all observations on the cumulative # incidence of the outcome. A <- "trt" Y <- paste0("Y.", 1:6) C <- paste0("C.", 0:5) W <- c("W1", "W2") curve <- lmtp_survival(sim_point_surv, A, Y, W, cens = C, folds = 1, shift = static_binary_on, estimator = "lmtp_tmle") tidy(curve) # Example 1.2 # Time-to-event analysis with a binary time-invariant exposure and a competing-risk. lmtp_survival( data = sim_competing_risks, trt = "A", cens = paste0("C", 1:5), compete = paste0("D", 1:5), baseline = paste0("W", 1:5), outcome = paste0("Y", 1:5), shift = static_binary_on, folds = 1 )
Targeted maximum likelihood estimator for the effects of traditional causal effects and modified treatment policies for both point treatment and longitudinal data with binary, continuous, or time-to-event outcomes. Supports binary, categorical, and continuous exposures.
lmtp_tmle( data, trt, outcome, baseline = NULL, time_vary = NULL, cens = NULL, compete = NULL, shift = NULL, shifted = NULL, k = Inf, mtp = FALSE, outcome_type = c("binomial", "continuous", "survival"), id = NULL, bounds = NULL, learners_outcome = "SL.glm", learners_trt = "SL.glm", folds = 10, weights = NULL, control = lmtp_control() )
lmtp_tmle( data, trt, outcome, baseline = NULL, time_vary = NULL, cens = NULL, compete = NULL, shift = NULL, shifted = NULL, k = Inf, mtp = FALSE, outcome_type = c("binomial", "continuous", "survival"), id = NULL, bounds = NULL, learners_outcome = "SL.glm", learners_trt = "SL.glm", folds = 10, weights = NULL, control = lmtp_control() )
data |
[ |
trt |
[ |
outcome |
[ |
baseline |
[ |
time_vary |
[ |
cens |
[ |
compete |
[ |
shift |
[ |
shifted |
[ |
k |
[ |
mtp |
[ |
outcome_type |
[ |
id |
[ |
bounds |
[ |
learners_outcome |
[ |
learners_trt |
[ |
folds |
[ |
weights |
[ |
control |
[ |
mtp = TRUE
?A modified treatment policy (MTP) is an intervention that depends
on the natural value of the exposure (the value that the treatment would have taken under no intervention).
This differs from other causal effects,
such as the average treatment effect (ATE), where an exposure would be increased (or decreased) deterministically.
If your intervention of interest adds, subtracts, or multiplies the observed treatment values
by some amount, use mtp = TRUE
.
A list of class lmtp
containing the following components:
estimator |
The estimator used, in this case "TMLE". |
estimates |
The estimated population LMTP effect as an |
shift |
The shift function specifying the treatment policy of interest. |
outcome_reg |
An n x Tau + 1 matrix of outcome regression predictions. The mean of the first column is used for calculating theta. |
density_ratios |
An n x Tau matrix of the estimated, non-cumulative, density ratios. |
fits_m |
A list the same length as |
fits_r |
A list the same length as |
outcome_type |
The outcome variable type. |
set.seed(56) n <- 1000 W <- rnorm(n, 10, 5) A <- 23 + 5*W + rnorm(n) Y <- 7.2*A + 3*W + rnorm(n) ex1_dat <- data.frame(W, A, Y) # Example 1.1 # Point treatment, continuous exposure, continuous outcome, no loss-to-follow-up # Interested in the effect of a modified treatment policy where A is decreased by 15 # units only among observations whose observed A was above 80. # The true value under this intervention is about 513. policy <- function(data, x) { (data[[x]] > 80)*(data[[x]] - 15) + (data[[x]] <= 80)*data[[x]] } lmtp_tmle(ex1_dat, "A", "Y", "W", shift = policy, outcome_type = "continuous", folds = 2, mtp = TRUE) # Example 2.1 # Longitudinal setting, time-varying continuous exposure bounded by 0, # time-varying covariates, and a binary outcome with no loss-to-follow-up. # Interested in the effect of a treatment policy where exposure decreases by # one unit at every time point if an observations observed exposure is greater # than or equal to 2. The true value under this intervention is about 0.305. head(sim_t4) A <- c("A_1", "A_2", "A_3", "A_4") L <- list(c("L_1"), c("L_2"), c("L_3"), c("L_4")) policy <- function(data, trt) { a <- data[[trt]] (a - 1) * (a - 1 >= 1) + a * (a - 1 < 1) } # BONUS: progressr progress bars! progressr::handlers(global = TRUE) lmtp_tmle(sim_t4, A, "Y", time_vary = L, shift = policy, folds = 2, mtp = TRUE) # Example 2.2 # The previous example assumed that the outcome (as well as the treatment variables) # were directly affected by all other nodes in the past. In certain situations, # domain specific knowledge may suggest otherwise. # This can be controlled using the k argument. lmtp_tmle(sim_t4, A, "Y", time_vary = L, shift = policy, k = 0, folds = 2, mtp = TRUE) # Example 2.3 # Using the same data as examples 2.1 and 2.2. # Now estimating the effect of a dynamic modified treatment policy. # creating a dynamic mtp that applies the shift function # but also depends on history and the current time policy <- function(data, trt) { mtp <- function(data, trt) { (data[[trt]] - 1) * (data[[trt]] - 1 >= 1) + data[[trt]] * (data[[trt]] - 1 < 1) } # if its the first time point, follow the same mtp as before if (trt == "A_1") return(mtp(data, trt)) # otherwise check if the time varying covariate equals 1 ifelse( data[[sub("A", "L", trt)]] == 1, mtp(data, trt), # if yes continue with the policy data[[trt]] # otherwise do nothing ) } lmtp_tmle(sim_t4, A, "Y", time_vary = L, mtp = TRUE, k = 0, shift = policy, folds = 2) # Example 2.4 # Using the same data as examples 2.1, 2.2, and 2.3, but now treating the exposure # as an ordered categorical variable. To account for the exposure being a # factor we just need to modify the shift function (and the original data) # so as to respect this. tmp <- sim_t4 for (i in A) { tmp[[i]] <- factor(tmp[[i]], levels = 0:5, ordered = FALSE) } policy <- function(data, trt) { out <- list() a <- data[[trt]] for (i in 1:length(a)) { if (as.character(a[i]) %in% c("0", "1")) { out[[i]] <- as.character(a[i]) } else { out[[i]] <- as.numeric(as.character(a[i])) - 1 } } factor(unlist(out), levels = 0:5, ordered = FALSE) } lmtp_tmle(tmp, A, "Y", time_vary = L, shift = policy, k = 0, folds = 2, mtp = TRUE) # Example 3.1 # Longitudinal setting, time-varying binary treatment, time-varying covariates # and baseline covariates with no loss-to-follow-up. Interested in a "traditional" # causal effect where treatment is set to 1 at all time points for all observations. if (require("twang")) { data("iptwExWide", package = "twang") A <- paste0("tx", 1:3) W <- c("gender", "age") L <- list(c("use0"), c("use1"), c("use2")) lmtp_tmle(iptwExWide, A, "outcome", baseline = W, time_vary = L, shift = static_binary_on, outcome_type = "continuous", mtp = FALSE, folds = 2) } # Example 4.1 # Longitudinal setting, time-varying continuous treatment, time-varying covariates, # binary outcome with right censoring. Interested in the mean population outcome under # the observed exposures in a hypothetical population with no loss-to-follow-up. head(sim_cens) A <- c("A1", "A2") L <- list(c("L1"), c("L2")) C <- c("C1", "C2") Y <- "Y" lmtp_tmle(sim_cens, A, Y, time_vary = L, cens = C, shift = NULL, folds = 2) # Example 5.1 # Time-to-event analysis with a binary time-invariant exposure. Interested in # the effect of treatment being given to all observations on the cumulative # incidence of the outcome. # For a survival problem, the outcome argument now takes a vector of outcomes # if an observation experiences the event prior to the end of follow-up, all future # outcome nodes should be set to 1 (i.e., last observation carried forward). A <- "trt" Y <- paste0("Y.", 1:6) C <- paste0("C.", 0:5) W <- c("W1", "W2") lmtp_tmle(sim_point_surv, A, Y, W, cens = C, folds = 2, shift = static_binary_on, outcome_type = "survival") # Example 6.1 # Intervening on multiple exposures simultaneously. Interested in the effect of # a modified treatment policy where variable D1 is decreased by 0.1 units and # variable D2 is decreased by 0.5 units simultaneously. A <- list(c("D1", "D2")) W <- paste0("C", 1:3) Y <- "Y" d <- function(data, a) { out = list( data[[a[1]]] - 0.1, data[[a[2]]] - 0.5 ) setNames(out, a) } lmtp_tmle(multivariate_data, A, Y, W, shift = d, outcome_type = "continuous", folds = 1, mtp = TRUE) # Example 7.1 # Time-to-event analysis with a binary time-invariant exposure and a competing-risk. lmtp_tmle( data = sim_competing_risks, trt = "A", cens = paste0("C", 1:5), compete = paste0("D", 1:5), baseline = paste0("W", 1:5), outcome = paste0("Y", 1:5), outcome_type = "survival", shift = static_binary_on, folds = 1 )
set.seed(56) n <- 1000 W <- rnorm(n, 10, 5) A <- 23 + 5*W + rnorm(n) Y <- 7.2*A + 3*W + rnorm(n) ex1_dat <- data.frame(W, A, Y) # Example 1.1 # Point treatment, continuous exposure, continuous outcome, no loss-to-follow-up # Interested in the effect of a modified treatment policy where A is decreased by 15 # units only among observations whose observed A was above 80. # The true value under this intervention is about 513. policy <- function(data, x) { (data[[x]] > 80)*(data[[x]] - 15) + (data[[x]] <= 80)*data[[x]] } lmtp_tmle(ex1_dat, "A", "Y", "W", shift = policy, outcome_type = "continuous", folds = 2, mtp = TRUE) # Example 2.1 # Longitudinal setting, time-varying continuous exposure bounded by 0, # time-varying covariates, and a binary outcome with no loss-to-follow-up. # Interested in the effect of a treatment policy where exposure decreases by # one unit at every time point if an observations observed exposure is greater # than or equal to 2. The true value under this intervention is about 0.305. head(sim_t4) A <- c("A_1", "A_2", "A_3", "A_4") L <- list(c("L_1"), c("L_2"), c("L_3"), c("L_4")) policy <- function(data, trt) { a <- data[[trt]] (a - 1) * (a - 1 >= 1) + a * (a - 1 < 1) } # BONUS: progressr progress bars! progressr::handlers(global = TRUE) lmtp_tmle(sim_t4, A, "Y", time_vary = L, shift = policy, folds = 2, mtp = TRUE) # Example 2.2 # The previous example assumed that the outcome (as well as the treatment variables) # were directly affected by all other nodes in the past. In certain situations, # domain specific knowledge may suggest otherwise. # This can be controlled using the k argument. lmtp_tmle(sim_t4, A, "Y", time_vary = L, shift = policy, k = 0, folds = 2, mtp = TRUE) # Example 2.3 # Using the same data as examples 2.1 and 2.2. # Now estimating the effect of a dynamic modified treatment policy. # creating a dynamic mtp that applies the shift function # but also depends on history and the current time policy <- function(data, trt) { mtp <- function(data, trt) { (data[[trt]] - 1) * (data[[trt]] - 1 >= 1) + data[[trt]] * (data[[trt]] - 1 < 1) } # if its the first time point, follow the same mtp as before if (trt == "A_1") return(mtp(data, trt)) # otherwise check if the time varying covariate equals 1 ifelse( data[[sub("A", "L", trt)]] == 1, mtp(data, trt), # if yes continue with the policy data[[trt]] # otherwise do nothing ) } lmtp_tmle(sim_t4, A, "Y", time_vary = L, mtp = TRUE, k = 0, shift = policy, folds = 2) # Example 2.4 # Using the same data as examples 2.1, 2.2, and 2.3, but now treating the exposure # as an ordered categorical variable. To account for the exposure being a # factor we just need to modify the shift function (and the original data) # so as to respect this. tmp <- sim_t4 for (i in A) { tmp[[i]] <- factor(tmp[[i]], levels = 0:5, ordered = FALSE) } policy <- function(data, trt) { out <- list() a <- data[[trt]] for (i in 1:length(a)) { if (as.character(a[i]) %in% c("0", "1")) { out[[i]] <- as.character(a[i]) } else { out[[i]] <- as.numeric(as.character(a[i])) - 1 } } factor(unlist(out), levels = 0:5, ordered = FALSE) } lmtp_tmle(tmp, A, "Y", time_vary = L, shift = policy, k = 0, folds = 2, mtp = TRUE) # Example 3.1 # Longitudinal setting, time-varying binary treatment, time-varying covariates # and baseline covariates with no loss-to-follow-up. Interested in a "traditional" # causal effect where treatment is set to 1 at all time points for all observations. if (require("twang")) { data("iptwExWide", package = "twang") A <- paste0("tx", 1:3) W <- c("gender", "age") L <- list(c("use0"), c("use1"), c("use2")) lmtp_tmle(iptwExWide, A, "outcome", baseline = W, time_vary = L, shift = static_binary_on, outcome_type = "continuous", mtp = FALSE, folds = 2) } # Example 4.1 # Longitudinal setting, time-varying continuous treatment, time-varying covariates, # binary outcome with right censoring. Interested in the mean population outcome under # the observed exposures in a hypothetical population with no loss-to-follow-up. head(sim_cens) A <- c("A1", "A2") L <- list(c("L1"), c("L2")) C <- c("C1", "C2") Y <- "Y" lmtp_tmle(sim_cens, A, Y, time_vary = L, cens = C, shift = NULL, folds = 2) # Example 5.1 # Time-to-event analysis with a binary time-invariant exposure. Interested in # the effect of treatment being given to all observations on the cumulative # incidence of the outcome. # For a survival problem, the outcome argument now takes a vector of outcomes # if an observation experiences the event prior to the end of follow-up, all future # outcome nodes should be set to 1 (i.e., last observation carried forward). A <- "trt" Y <- paste0("Y.", 1:6) C <- paste0("C.", 0:5) W <- c("W1", "W2") lmtp_tmle(sim_point_surv, A, Y, W, cens = C, folds = 2, shift = static_binary_on, outcome_type = "survival") # Example 6.1 # Intervening on multiple exposures simultaneously. Interested in the effect of # a modified treatment policy where variable D1 is decreased by 0.1 units and # variable D2 is decreased by 0.5 units simultaneously. A <- list(c("D1", "D2")) W <- paste0("C", 1:3) Y <- "Y" d <- function(data, a) { out = list( data[[a[1]]] - 0.1, data[[a[2]]] - 0.5 ) setNames(out, a) } lmtp_tmle(multivariate_data, A, Y, W, shift = d, outcome_type = "continuous", folds = 1, mtp = TRUE) # Example 7.1 # Time-to-event analysis with a binary time-invariant exposure and a competing-risk. lmtp_tmle( data = sim_competing_risks, trt = "A", cens = paste0("C", 1:5), compete = paste0("D", 1:5), baseline = paste0("W", 1:5), outcome = paste0("Y", 1:5), outcome_type = "survival", shift = static_binary_on, folds = 1 )
A dataset with a continuous outcome, three baseline covariates, and two treatment variables.
multivariate_data
multivariate_data
A data frame with 2000 rows and 6 variables:
Continuous baseline variable.
Continuous baseline variable.
Continuous baseline variable.
Treatment variable one at baseline.
Treatment variable two at baseline.
Continuous outcome
A dataset with a binary outcome, two time varying treatment nodes, two time varying covariates, and two censoring indicators.
sim_cens
sim_cens
A data frame with 1000 rows and 10 variables:
Time varying covariate time 1
Treatment node at time 1, effected by L_1
Censoring indicator that the observation is observed after time 1
Time varying covariate at time 2, effected by L_1 and A_1
Treatment node at time 2, effected by L_2 and A_1
Censoring indicator that the observation is observed after time 2
Binary outcome at time 3, effected by L_2 and A_2
A dataset with a time-to-event outcome, a competing risk, and point-treatment.
sim_competing_risks
sim_competing_risks
A data frame with 1000 rows and 21 variables.
A dataset with a time-to-event outcome, two baseline nodes, a binary point treatment, six past-time outcome nodes, and six censoring indicators.
sim_point_surv
sim_point_surv
A data frame with 2000 rows and 16 variables:
Binary baseline variable.
Categorical baseline variable.
Binary treatment variable.
Censoring indicator that the observation is observed future time points.
Outcome node at time 1.
Censoring indicator that the observation is observed future time points.
Outcome node at time 2.
Censoring indicator that the observation is observed future time points.
Outcome node at time 3.
Censoring indicator that the observation is observed future time points.
Outcome node at time 4.
Censoring indicator that the observation is observed future time points.
Outcome node at time 5.
Censoring indicator that the observation is observed future time points.
Final outcome node.
A dataset with a binary outcome, four time varying treatment nodes, and four time varying covariates.
sim_t4
sim_t4
A data frame with 5000 rows and 10 variables:
observation ID
Time varying covariate time 1
Treatment node at time 1, effected by L_1
Time varying covariate time 1, effected by L_1 and A_1
Treatment node at time 2, effected by L_2 and A_1
Time varying covariate time 1, effected by L_2 and A_2
Treatment node at time 3, effected by L_3 and A_2
Time varying covariate time 1, effected by L_3 and A_3
Treatment node at time 3, effected by L_4 and A_3
Binary outcome at time 5, effected by L_4 and A_4
A dataset with a time-to-event outcome, one baseline nodes, two time-varying covariates, a binary time-varying treatment, two outcome nodes, and two censoring indicators. Data-generating mechanism taken from Lendle, Schwab, Petersen, and van der Laan (https://www.jstatsoft.org/article/view/v081i01).
sim_timevary_surv
sim_timevary_surv
A data frame with 500 rows and 11 variables:
Continuous baseline variable.
Time varying covariate at baseline.
Time varying covariate at baseline.
Treatment variable at baseline
Censoring indicator that the observation is observed future time points.
Time varying covariate at time 1.
Time varying covariate at time 1.
Outcome node at time 1.
Treatment variable at time 1.
Censoring indicator that the observation is observed future time points.
Final outcome node.
A pre-packaged shift function for use with provided estimators when the exposure is binary. Used to estimate the population intervention effect when all treatment variables are set to 0.
static_binary_off(data, trt)
static_binary_off(data, trt)
data |
A dataframe containing the treatment variables. |
trt |
The name of the current treatment variable. |
A dataframe with all treatment nodes set to 0.
data("iptwExWide", package = "twang") a <- paste0("tx", 1:3) baseline <- c("gender", "age") tv <- list(c("use0"), c("use1"), c("use2")) lmtp_sdr(iptwExWide, a, "outcome", baseline = baseline, time_vary = tv, shift = static_binary_off, outcome_type = "continuous", folds = 2)
data("iptwExWide", package = "twang") a <- paste0("tx", 1:3) baseline <- c("gender", "age") tv <- list(c("use0"), c("use1"), c("use2")) lmtp_sdr(iptwExWide, a, "outcome", baseline = baseline, time_vary = tv, shift = static_binary_off, outcome_type = "continuous", folds = 2)
A pre-packaged shift function for use with provided estimators when the exposure is binary. Used to estimate the population intervention effect when all treatment variables are set to 1.
static_binary_on(data, trt)
static_binary_on(data, trt)
data |
A dataframe containing the treatment variables. |
trt |
The name of the current treatment variable. |
A dataframe with all treatment nodes set to 1.
data("iptwExWide", package = "twang") a <- paste0("tx", 1:3) baseline <- c("gender", "age") tv <- list(c("use0"), c("use1"), c("use2")) lmtp_sdr(iptwExWide, a, "outcome", baseline = baseline, time_vary = tv, shift = static_binary_on, outcome_type = "continuous", folds = 2)
data("iptwExWide", package = "twang") a <- paste0("tx", 1:3) baseline <- c("gender", "age") tv <- list(c("use0"), c("use1"), c("use2")) lmtp_sdr(iptwExWide, a, "outcome", baseline = baseline, time_vary = tv, shift = static_binary_on, outcome_type = "continuous", folds = 2)
Tidy a(n) lmtp object
## S3 method for class 'lmtp' tidy(x, ...)
## S3 method for class 'lmtp' tidy(x, ...)
x |
A |
... |
Unused, included for generic consistency only. |
a <- c("A1", "A2") nodes <- list(c("L1"), c("L2")) cens <- c("C1", "C2") y <- "Y" fit <- lmtp_tmle(sim_cens, a, y, time_vary = nodes, cens = cens, shift = NULL, folds = 2) tidy(fit)
a <- c("A1", "A2") nodes <- list(c("L1"), c("L2")) cens <- c("C1", "C2") y <- "Y" fit <- lmtp_tmle(sim_cens, a, y, time_vary = nodes, cens = cens, shift = NULL, folds = 2) tidy(fit)
Tidy a(n) lmtp_survival object
## S3 method for class 'lmtp_survival' tidy(x, ...)
## S3 method for class 'lmtp_survival' tidy(x, ...)
x |
A |
... |
Unused, included for generic consistency only. |
# Example 1.1 # Time-to-event analysis with a binary time-invariant exposure. Interested in # the effect of treatment being given to all observations on the cumulative # incidence of the outcome. A <- "trt" Y <- paste0("Y.", 1:6) C <- paste0("C.", 0:5) W <- c("W1", "W2") curve <- lmtp_survival(sim_point_surv, A, Y, W, cens = C, folds = 1, shift = static_binary_on, estimator = "lmtp_tmle") tidy(curve) # Example 1.2 # Time-to-event analysis with a binary time-invariant exposure and a competing-risk. lmtp_survival( data = sim_competing_risks, trt = "A", cens = paste0("C", 1:5), compete = paste0("D", 1:5), baseline = paste0("W", 1:5), outcome = paste0("Y", 1:5), shift = static_binary_on, folds = 1 )
# Example 1.1 # Time-to-event analysis with a binary time-invariant exposure. Interested in # the effect of treatment being given to all observations on the cumulative # incidence of the outcome. A <- "trt" Y <- paste0("Y.", 1:6) C <- paste0("C.", 0:5) W <- c("W1", "W2") curve <- lmtp_survival(sim_point_surv, A, Y, W, cens = C, folds = 1, shift = static_binary_on, estimator = "lmtp_tmle") tidy(curve) # Example 1.2 # Time-to-event analysis with a binary time-invariant exposure and a competing-risk. lmtp_survival( data = sim_competing_risks, trt = "A", cens = paste0("C", 1:5), compete = paste0("D", 1:5), baseline = paste0("W", 1:5), outcome = paste0("Y", 1:5), shift = static_binary_on, folds = 1 )