## ----setup, include = FALSE--------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 5 ) ## ----example-setup------------------------------------------------------------ library(causaldef) set.seed(42) n <- 500 U <- rnorm(n) # Unmeasured confounder W <- 0.7 * U + rnorm(n, sd = 0.5) # Observed covariate A <- rbinom(n, 1, plogis(0.5 * U)) # Treatment Y <- 2 * A + 1.5 * U + rnorm(n) # Outcome (true effect = 2) df <- data.frame(W = W, A = A, Y = Y) spec <- causal_spec(df, "A", "Y", "W") ## ----deficiency-calc---------------------------------------------------------- def_results <- estimate_deficiency( spec, methods = c("unadjusted", "iptw"), n_boot = 100 ) print(def_results) ## ----frontier-plot, fig.height=5---------------------------------------------- frontier <- confounding_frontier( spec, alpha_range = c(-3, 3), gamma_range = c(-3, 3), grid_size = 40 ) plot(frontier) ## ----policy-bound------------------------------------------------------------- bounds <- policy_regret_bound(def_results, utility_range = c(0, 10), method = "iptw") print(bounds) ## ----evalue-calculation------------------------------------------------------- # Effect estimate effect <- estimate_effect(def_results, target_method = "iptw") print(effect) # For E-value calculation, we need to convert to risk ratio scale # This is an approximation; exact E-values require binary outcomes # Here we use the standardized effect size # Assuming effect is on continuous scale, we can compute # a pseudo-risk ratio via effect size transformation effect_se <- 1 # Approximate SE (would be from bootstrap in practice) effect_est <- effect$estimate t_stat <- effect_est / effect_se # Approximate conversion to OR (for conceptual illustration) # Using Chinn's (2000) formula for approximate OR from mean difference approx_or <- exp(effect_est / 1.81) # E-value formula if (approx_or > 1) { e_value <- approx_or + sqrt(approx_or * (approx_or - 1)) } else { e_value <- 1 / approx_or + sqrt(1 / approx_or * (1 / approx_or - 1)) } cat(sprintf(" Approximate E-value: %.2f Interpretation: To explain away the observed effect, an unmeasured confounder would need a risk ratio of at least %.2f with both treatment and outcome. ", e_value, e_value)) ## ----benchmark---------------------------------------------------------------- # Add more covariates for benchmarking df$W2 <- 0.3 * U + rnorm(n, sd = 0.8) df$W3 <- 0.9 * U + rnorm(n, sd = 0.3) spec_multi <- causal_spec(df, "A", "Y", c("W", "W2", "W3")) frontier_bench <- confounding_frontier( spec_multi, grid_size = 40 ) # Access benchmarks if (!is.null(frontier_bench$benchmarks)) { print(frontier_bench$benchmarks) } ## ----full-analysis------------------------------------------------------------ # Add negative control df$Y_nc <- U + rnorm(n, sd = 0.5) # Affected by U, not by A spec_full <- causal_spec( df, "A", "Y", c("W", "W2", "W3"), negative_control = "Y_nc" ) # Complete analysis def_full <- estimate_deficiency( spec_full, methods = c("unadjusted", "iptw"), n_boot = 100 ) nc_full <- nc_diagnostic(spec_full, method = "iptw", n_boot = 100) print(def_full) print(nc_full)