| Title: | Cross-Framework Causal Fragility Index |
|---|---|
| Description: | Provides a unified workflow for running, classifying, visualizing, and interpreting sensitivity analyses for unmeasured confounding across multiple causal frameworks. Introduces the Causal Fragility Index (CFI), a single 0-100 composite score that integrates evidence from the partial R-squared robustness value approach (Cinelli and Hazlett, 2020, <doi:10.1111/rssb.12348>), E-value metrics (VanderWeele and Ding, 2017, <doi:10.7326/M16-2607>), and the Impact Threshold for a Confounding Variable (Frank, 2000, <doi:10.1177/0049124100029002001>) into one interpretable measure of robustness. The package also provides template-based plain-language narrative interpretation and publication-ready reporting, with optional integration with the 'confoundvis' package for sensitivity plots. |
| Authors: | Subir Hait [aut, cre] (ORCID: <https://orcid.org/0009-0004-9871-9677>) |
| Maintainer: | Subir Hait <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.1 |
| Built: | 2026-06-16 12:34:02 UTC |
| Source: | https://github.com/causalfragility-lab/causalfrag |
causalfrag provides a unified workflow for running, classifying, visualizing, and interpreting sensitivity analyses for unmeasured confounding across multiple causal frameworks.
The core contribution is the Causal Fragility Index (CFI): a single 0–100 composite score that integrates sensitivity evidence across frameworks into one interpretable measure of robustness.
“'r fit <- lm(outcome ~ treatment + covariates, data = mydata) res <- run_sensitivity(fit, treatment = "treatment", data = mydata) res <- flag_fragility(res) # also computes CFI automatically print(res) # shows CFI score + component breakdown print_cfi(res) # dedicated CFI display generate_report(res) # full structured report “'
The CFI combines evidence from up to four sensitivity components:
RV (point): Robustness Value for point-estimate nullification
RV (significance): Robustness Value for statistical significance
E-value: Risk-ratio style confounding strength
Pct bias: Percent bias needed to invalidate (ITCV)
sensemakr: Cinelli & Hazlett (2020) partial R-squared approach
EValue: VanderWeele & Ding (2017) E-value metrics
konfound: Frank (2000) Impact Threshold (ITCV)
rbounds: Rosenbaum (2002) bounds for matched designs
confoundvis (Hait, 2026) provides visualization tools for sensitivity analysis. causalfrag provides the unified fragility scoring, interpretation, and reporting layer that optionally uses confoundvis graphics as part of the workflow.
Subir Hait [email protected]
Frank, K. A. (2000). Impact of a confounding variable on the inference of a regression coefficient. Sociological Methods & Research, 29(2), 147–194. doi:10.1177/0049124100029002001
Cinelli, C., & Hazlett, C. (2020). Making sense of sensitivity: Extending omitted variable bias. Journal of the Royal Statistical Society: Series B, 82(1), 39–67. doi:10.1111/rssb.12348
VanderWeele, T. J., & Ding, P. (2017). Sensitivity analysis in observational research: Introducing the E-value. Annals of Internal Medicine, 167(4), 268–274. doi:10.7326/M16-2607
Useful links:
Report bugs at https://github.com/causalfragility-lab/causalfrag/issues
Produces a side-by-side comparison table of CFI scores and fragility
classifications across two or more sens_results objects. Useful
for comparing policy interventions or treatment arms.
compare_cfi(...)compare_cfi(...)
... |
Two or more named |
A data frame with one row per treatment and columns:
treatment, outcome, cfi, label,
point_fragility, significance_fragility,
rv_q, evalue, pct_bias.
if (requireNamespace("sensemakr", quietly = TRUE)) { data("darfur", package = "sensemakr") fit_a <- lm(peacefactor ~ directlyharmed + age + female, data = darfur) fit_b <- lm(peacefactor ~ herder_dar + age + female, data = darfur) res_a <- run_sensitivity(fit_a, "directlyharmed", darfur, verbose = FALSE) res_b <- run_sensitivity(fit_b, "herder_dar", darfur, verbose = FALSE) res_a <- flag_fragility(res_a) res_b <- flag_fragility(res_b) compare_cfi( "Directly harmed" = res_a, "Herder" = res_b ) }if (requireNamespace("sensemakr", quietly = TRUE)) { data("darfur", package = "sensemakr") fit_a <- lm(peacefactor ~ directlyharmed + age + female, data = darfur) fit_b <- lm(peacefactor ~ herder_dar + age + female, data = darfur) res_a <- run_sensitivity(fit_a, "directlyharmed", darfur, verbose = FALSE) res_b <- run_sensitivity(fit_b, "herder_dar", darfur, verbose = FALSE) res_a <- flag_fragility(res_a) res_b <- flag_fragility(res_b) compare_cfi( "Directly harmed" = res_a, "Herder" = res_b ) }
The Causal Fragility Index (CFI) is a single 0–100 composite score that integrates sensitivity evidence across multiple causal frameworks into one interpretable measure of robustness.
Each framework contributes one or more component scores, which are averaged into the final CFI. Higher scores indicate greater robustness to unmeasured confounding.
compute_cfi(x, weights = NULL)compute_cfi(x, weights = NULL)
x |
A |
weights |
Optional named numeric vector to weight components.
Names must match: |
The input sens_results object with $cfi populated
as a named list with elements:
Numeric 0–100. The overall CFI.
Character. CFI classification label.
Named numeric vector of component scores.
Character. One-sentence plain-language summary.
| Component | Rule | Full score at |
| RV (point) | rv / 0.20 * 100 | RV >= 0.20 |
| RV (significance) | rv_alpha / 0.10 * 100 | RV >= 0.10 |
| E-value | (evalue - 1) / 2.0 * 100 | E-value >= 3 |
| Percent bias | pct_bias (direct) | pct >= 100 |
| CFI range | Label |
| 0 -- 24 | Fragile |
| 25 -- 49 | Moderately fragile |
| 50 -- 74 | Moderately robust |
| 75 -- 100 | Robust |
res <- new_sens_results( design = "regression", treatment = "directlyharmed", outcome = "peacefactor", frameworks = c("sensemakr", "evalue", "itcv"), results = list( sensemakr = list(rv_q = 0.139, rv_qa = 0.076, r2yd_x = 0.022, estimate = 0.097), evalue = list(evalue = 1.90, evalue_lower = 1.55, estimate = 0.097), itcv = list(itcv = 0.065, rir = 678, pct_bias = 53.1) ) ) res <- compute_cfi(res) print_cfi(res)res <- new_sens_results( design = "regression", treatment = "directlyharmed", outcome = "peacefactor", frameworks = c("sensemakr", "evalue", "itcv"), results = list( sensemakr = list(rv_q = 0.139, rv_qa = 0.076, r2yd_x = 0.022, estimate = 0.097), evalue = list(evalue = 1.90, evalue_lower = 1.55, estimate = 0.097), itcv = list(itcv = 0.065, rir = 678, pct_bias = 53.1) ) ) res <- compute_cfi(res) print_cfi(res)
Extends the CFI with benchmark-relative interpretation. Rather than assessing fragility against absolute thresholds, the benchmark-adjusted CFI compares the required confounding strength to the observed association of a named covariate with treatment and outcome.
This answers: "Would an omitted confounder need to be stronger than
benchmark_covariate to overturn the conclusion?"
compute_cfi_benchmarked(x, benchmark_covariate, kd = 1)compute_cfi_benchmarked(x, benchmark_covariate, kd = 1)
x |
A |
benchmark_covariate |
Character. Name of the covariate to benchmark against. Must be a covariate in the original model. |
kd |
Numeric. Multiplier for treatment partial R-squared in benchmark. Default 1 (benchmark at 1x covariate strength). |
The input sens_results object with $cfi_benchmarked
populated as a named list with elements:
Ratio: RV / benchmark partial R-squared (treat).
Same for significance threshold.
Plain-language benchmark statement.
Logical. Does required confounding exceed the benchmark covariate's strength?
if (requireNamespace("sensemakr", quietly = TRUE)) { data("darfur", package = "sensemakr") fit <- lm(peacefactor ~ directlyharmed + age + female + village, data = darfur) res <- run_sensitivity(fit, treatment = "directlyharmed", data = darfur, benchmark_covariates = "female") res <- compute_cfi_benchmarked(res, benchmark_covariate = "female") cat(res$cfi_benchmarked$benchmark_label) }if (requireNamespace("sensemakr", quietly = TRUE)) { data("darfur", package = "sensemakr") fit <- lm(peacefactor ~ directlyharmed + age + female + village, data = darfur) res <- run_sensitivity(fit, treatment = "directlyharmed", data = darfur, benchmark_covariates = "female") res <- compute_cfi_benchmarked(res, benchmark_covariate = "female") cat(res$cfi_benchmarked$benchmark_label) }
Extends compute_cfi() with named weight presets and user-defined
weights. Different sensitivity frameworks carry different evidential weight
depending on the study design and analyst priorities.
compute_cfi_weighted(x, weights = "balanced")compute_cfi_weighted(x, weights = "balanced")
x |
A |
weights |
Character preset or named numeric vector.
Character: one of |
The input sens_results object with $cfi updated.
Equal weight to all available components (default).
Double weight on both Robustness Value components. Use when the partial R-squared framework is most relevant.
Double weight on E-value. Use when risk-ratio framing is most natural (e.g. binary outcomes, relative risks).
Double weight on percent bias (ITCV/konfound). Use when case-replacement interpretability is prioritised.
Presets are transparent defaults, not discipline-specific claims. Present chosen weights explicitly when reporting results.
if (requireNamespace("sensemakr", quietly = TRUE)) { data("darfur", package = "sensemakr") fit <- lm(peacefactor ~ directlyharmed + age + female, data = darfur) res <- run_sensitivity(fit, treatment = "directlyharmed", data = darfur) res <- compute_cfi_weighted(res, weights = "rv_priority") print_cfi(res) }if (requireNamespace("sensemakr", quietly = TRUE)) { data("darfur", package = "sensemakr") fit <- lm(peacefactor ~ directlyharmed + age + female, data = darfur) res <- run_sensitivity(fit, treatment = "directlyharmed", data = darfur) res <- compute_cfi_weighted(res, weights = "rv_priority") print_cfi(res) }
Inspects a fitted model object and returns the most appropriate sensitivity analysis design type. The detected design determines which sensitivity frameworks are run by 'run_sensitivity()'.
Users can always override the detected design manually via the 'design' argument in 'sens_report()' or 'run_sensitivity()'.
detect_design(model, verbose = TRUE)detect_design(model, verbose = TRUE)
model |
A fitted model object. Supported classes:
|
verbose |
Logical. If 'TRUE', prints the detected design. Default 'TRUE'. |
A character string: one of '"regression"', '"matched"', '"survival"', '"iv"', or '"unknown"'.
fit <- lm(mpg ~ am + wt + hp, data = mtcars) detect_design(fit)fit <- lm(mpg ~ am + wt + hp, data = mtcars) detect_design(fit)
Inspects a fitted sensemakr object and returns a clean named list
with correctly mapped field names, ready to pass to new_sens_results().
This function exists because sensemakr internal field names
(rv_q, rv_qa) are not immediately obvious from the printed
output, and differ across versions. Always use this extractor rather than
accessing sm$sensitivity_stats directly.
extract_sensemakr(sm)extract_sensemakr(sm)
sm |
A |
A named list with elements:
Point estimate of the treatment effect.
Standard error.
t-statistic.
Partial R-squared of treatment with outcome.
Partial R-squared of treatment with treatment (benchmark).
Robustness Value for q=1 (point-estimate nullification).
Robustness Value for q=1, alpha=.05 (significance).
The original sensemakr object.
if (requireNamespace("sensemakr", quietly = TRUE)) { data("darfur", package = "sensemakr") fit <- lm(peacefactor ~ directlyharmed + age + female + village, data = darfur) sm <- sensemakr::sensemakr(fit, treatment = "directlyharmed") extract_sensemakr(sm) }if (requireNamespace("sensemakr", quietly = TRUE)) { data("darfur", package = "sensemakr") fit <- lm(peacefactor ~ directlyharmed + age + female + village, data = darfur) sm <- sensemakr::sensemakr(fit, treatment = "directlyharmed") extract_sensemakr(sm) }
Classifies the robustness of a causal conclusion using a five-level scale separately for (1) point-estimate nullification and (2) statistical significance, where supported by the framework.
flag_fragility(x, thresholds = NULL)flag_fragility(x, thresholds = NULL)
x |
A |
thresholds |
Optional named list to override default thresholds. |
The input sens_results object with $fragility
populated as a named list with elements point, alpha,
point_label, alpha_label.
| Level | RV threshold | Meaning |
| Highly stable | >= 0.20 | Very strong confounding needed |
| Stable | 0.10 -- 0.20 | Moderate confounding needed |
| Moderately fragile | 0.05 -- 0.10 | Plausible confounding could matter |
| Fragile | 0.01 -- 0.05 | Weak confounding could overturn result |
| Highly fragile | < 0.01 | Minimal confounding overturns result |
res <- new_sens_results( design = "regression", treatment = "t", outcome = "y", frameworks = "sensemakr", results = list(sensemakr = list(rv_q = 0.14, rv_qa = 0.08, r2yd_x = 0.02, estimate = 0.10)) ) res <- flag_fragility(res) res$fragilityres <- new_sens_results( design = "regression", treatment = "t", outcome = "y", frameworks = "sensemakr", results = list(sensemakr = list(rv_q = 0.14, rv_qa = 0.08, r2yd_x = 0.02, estimate = 0.10)) ) res <- flag_fragility(res) res$fragility
Produces a complete, structured report from a sens_results object.
The report includes study design, numeric results, fragility classification,
narrative interpretation, and suggested reporting language for academic papers.
Works fully offline without an API key. If interpret_sensitivity()
has not been run, the function runs it automatically using template-based
narratives.
generate_report( x, format = c("markdown", "text"), include_citation = TRUE, verbosity = "standard", file = NULL )generate_report( x, format = c("markdown", "text"), include_citation = TRUE, verbosity = "standard", file = NULL )
x |
A |
format |
Character. Output format. One of |
include_citation |
Logical. Append reference list. Default |
verbosity |
Character. Narrative verbosity passed to
|
file |
Character. Optional file path to write the report.
If |
Invisibly returns the report as a character string.
If file is specified, also writes to disk.
res <- new_sens_results( design = "regression", treatment = "directlyharmed", outcome = "peacefactor", frameworks = c("sensemakr", "evalue"), results = list( sensemakr = list(estimate = 0.097, r2yd_x = 0.022, rv_q = 0.139, rv_qa = 0.076), evalue = list(estimate = 0.097, evalue = 1.90, evalue_lower = 1.55) ), fragility = list(point = "Stable", alpha = "Moderately fragile", point_label = "RV = 13.9%", alpha_label = "RV = 7.6%") ) report <- generate_report(res) cat(report)res <- new_sens_results( design = "regression", treatment = "directlyharmed", outcome = "peacefactor", frameworks = c("sensemakr", "evalue"), results = list( sensemakr = list(estimate = 0.097, r2yd_x = 0.022, rv_q = 0.139, rv_qa = 0.076), evalue = list(estimate = 0.097, evalue = 1.90, evalue_lower = 1.55) ), fragility = list(point = "Stable", alpha = "Moderately fragile", point_label = "RV = 13.9%", alpha_label = "RV = 7.6%") ) report <- generate_report(res) cat(report)
Generates a concise plain-language interpretation (2-3 sentences per
framework) of sensitivity analysis findings. Uses an LLM if configured
via use_llm_provider(); falls back to pre-written concise templates
when no LLM is available.
The LLM assists only in phrasing. All statistical values come from the
sens_results object computed by transparent R functions.
interpret_sensitivity(x, verbosity = "standard", cache = TRUE, ...)interpret_sensitivity(x, verbosity = "standard", cache = TRUE, ...)
x |
A |
verbosity |
Character. Controls output length.
|
cache |
Logical. Cache the LLM response to avoid repeat API calls.
Default |
... |
Reserved for future use. |
The input sens_results object with $narrative
populated.
res <- new_sens_results( design = "regression", treatment = "directlyharmed", outcome = "peacefactor", frameworks = "sensemakr", results = list(sensemakr = list( rv_q = 0.139, rv_qa = 0.076, r2yd_x = 0.022, estimate = 0.097 )), fragility = list(point = "Stable", alpha = "Moderately fragile", point_label = "", alpha_label = "") ) res <- interpret_sensitivity(res) cat(res$narrative)res <- new_sens_results( design = "regression", treatment = "directlyharmed", outcome = "peacefactor", frameworks = "sensemakr", results = list(sensemakr = list( rv_q = 0.139, rv_qa = 0.076, r2yd_x = 0.022, estimate = 0.097 )), fragility = list(point = "Stable", alpha = "Moderately fragile", point_label = "", alpha_label = "") ) res <- interpret_sensitivity(res) cat(res$narrative)
Check if object is a sens_results
is_sens_results(x)is_sens_results(x)
x |
Any R object. |
Logical.
Constructor for the unified sens_results S3 class. This is the
central data structure that all causalfrag functions produce
and consume.
new_sens_results( design, treatment, outcome, frameworks, results, fragility = NULL, narrative = NULL, llm_used = FALSE, call = NULL )new_sens_results( design, treatment, outcome, frameworks, results, fragility = NULL, narrative = NULL, llm_used = FALSE, call = NULL )
design |
Character. Detected study design. One of |
treatment |
Character. Name of the treatment variable. |
outcome |
Character. Name of the outcome variable. |
frameworks |
Character vector. Which sensitivity frameworks were run. |
results |
Named list. Raw numeric results from each framework. |
fragility |
Named list with elements |
narrative |
Character. Plain-language interpretation. |
llm_used |
Logical. Whether an LLM was used for narrative generation. |
call |
The matched call. |
An object of class sens_results.
res <- new_sens_results( design = "regression", treatment = "treat", outcome = "outcome", frameworks = "sensemakr", results = list(sensemakr = list(rv_q = 0.14, rv_qa = 0.08, r2yd_x = 0.02, estimate = 0.10)) ) print(res)res <- new_sens_results( design = "regression", treatment = "treat", outcome = "outcome", frameworks = "sensemakr", results = list(sensemakr = list(rv_q = 0.14, rv_qa = 0.08, r2yd_x = 0.02, estimate = 0.10)) ) print(res)
Plot method for sens_results
## S3 method for class 'sens_results' plot(x, ...)## S3 method for class 'sens_results' plot(x, ...)
x |
A |
... |
Passed to |
Invisibly returns x, the unchanged sens_results
object. The method is called for its side effect of drawing a sensitivity plot.
Displays a formatted summary of the CFI score, component breakdown,
and interpretation. Call after compute_cfi().
print_cfi(x, ...)print_cfi(x, ...)
x |
A |
... |
Further arguments (unused). |
Invisibly returns x.
Print method for sens_results
## S3 method for class 'sens_results' print(x, ...)## S3 method for class 'sens_results' print(x, ...)
x |
A |
... |
Further arguments (unused). |
Invisibly returns x, the unchanged sens_results object.
The method is called for its side effect of printing a formatted summary.
Dispatches to the appropriate sensitivity analysis packages based on the detected or user-specified study design. Returns a unified 'sens_results' object containing numeric results from all frameworks run.
Each framework is called only if the required package is installed. Missing packages produce a warning, not an error, so the function always returns whatever results it can compute.
run_sensitivity( model, treatment, data, design = NULL, frameworks = NULL, benchmark_covariates = NULL, verbose = TRUE, ... )run_sensitivity( model, treatment, data, design = NULL, frameworks = NULL, benchmark_covariates = NULL, verbose = TRUE, ... )
model |
A fitted model object (e.g. from |
treatment |
Character. Name of the treatment variable. |
data |
A data frame containing the model variables. |
design |
Character. Study design. If |
frameworks |
Character vector. Which frameworks to run. If |
benchmark_covariates |
Character vector. Covariate names to use as
benchmarks in sensemakr. Default |
verbose |
Logical. Print progress messages. Default |
... |
Additional arguments (reserved for future use). |
A sens_results object with $results populated for
each framework successfully run.
if (requireNamespace("sensemakr", quietly = TRUE)) { data("darfur", package = "sensemakr") fit <- lm(peacefactor ~ directlyharmed + age + female + village, data = darfur) res <- run_sensitivity(fit, treatment = "directlyharmed", data = darfur) print(res) }if (requireNamespace("sensemakr", quietly = TRUE)) { data("darfur", package = "sensemakr") fit <- lm(peacefactor ~ directlyharmed + age + female + village, data = darfur) res <- run_sensitivity(fit, treatment = "directlyharmed", data = darfur) print(res) }
The main user-facing function. It runs the available sensitivity-analysis frameworks, classifies fragility, creates a narrative interpretation, and optionally draws a sensitivity plot when a supported plotting object is available.
sens_report( model, treatment, data, design = NULL, narrative = "standard", plot = TRUE, ... )sens_report( model, treatment, data, design = NULL, narrative = "standard", plot = TRUE, ... )
model |
A fitted model object (for example, from 'lm()' or 'glm()'). |
treatment |
Character. Name of the treatment variable in the model. |
data |
A data frame containing the variables in 'model'. |
design |
Character. Optional study-design override. One of '"regression"', '"matched"', '"iv"', or '"survival"'. The default, 'NULL', detects the design automatically. |
narrative |
Character. Narrative detail: '"brief"', '"standard"', or '"reviewer-ready"'. The default is '"standard"'. |
plot |
Logical. If 'TRUE', draw a sensitivity plot when the required plotting object and package are available. The default is 'TRUE'. |
... |
Additional arguments passed to 'run_sensitivity()'. |
A 'sens_results' object containing the framework-specific numeric results, fragility classifications, composite index when computable, and narrative interpretation. When 'plot = TRUE', a plot may also be produced as a side effect.
if (requireNamespace("sensemakr", quietly = TRUE)) { data("darfur", package = "sensemakr") fit <- lm(peacefactor ~ directlyharmed + age + female + village, data = darfur) result <- sens_report( fit, treatment = "directlyharmed", data = darfur, frameworks = "sensemakr", plot = FALSE ) print(result) }if (requireNamespace("sensemakr", quietly = TRUE)) { data("darfur", package = "sensemakr") fit <- lm(peacefactor ~ directlyharmed + age + female + village, data = darfur) result <- sens_report( fit, treatment = "directlyharmed", data = darfur, frameworks = "sensemakr", plot = FALSE ) print(result) }
Summary method for sens_results
## S3 method for class 'sens_results' summary(object, ...)## S3 method for class 'sens_results' summary(object, ...)
object |
A |
... |
Further arguments (unused). |
Invisibly returns object, the unchanged sens_results
object. The method is called for its side effect of printing a concise
summary of the study, frameworks, fragility assessment, and narrative status.
Sets up the LLM provider used by 'interpret_sensitivity()' and 'generate_report()'. Configuration is stored in the R session environment.
**The package works fully without calling this function.** When no LLM is configured, narrative output falls back to pre-written templates based on the numeric results.
use_llm_provider( provider = c("openai", "anthropic", "none"), api_key = NULL, model = NULL, max_tokens = 512L )use_llm_provider( provider = c("openai", "anthropic", "none"), api_key = NULL, model = NULL, max_tokens = 512L )
provider |
Character. One of '"openai"', '"anthropic"', '"none"'. Use '"none"' to explicitly disable LLM and use templates only. |
api_key |
Character. Your API key. If 'NULL', the function looks for environment variables 'OPENAI_API_KEY' or 'ANTHROPIC_API_KEY'. |
model |
Character. Model name to use.
|
max_tokens |
Integer. Maximum tokens for LLM response. Default 512. |
Invisibly returns a list of the current LLM configuration.
# Use Anthropic (key from environment variable) use_llm_provider("anthropic") # Use OpenAI with explicit key use_llm_provider("openai", api_key = "sk-...") # Disable LLM explicitly (template mode) use_llm_provider("none")# Use Anthropic (key from environment variable) use_llm_provider("anthropic") # Use OpenAI with explicit key use_llm_provider("openai", api_key = "sk-...") # Disable LLM explicitly (template mode) use_llm_provider("none")
Produces sensitivity analysis figures using sensemakr's built-in
plotting functions, or confoundvis if installed and engine
is set accordingly. Plots are generated for each framework in the
sens_results object that supports visualisation.
visualize_sensitivity(x, engine = "sensemakr", type = "contour", ...)visualize_sensitivity(x, engine = "sensemakr", type = "contour", ...)
x |
A |
engine |
Character. One of |
type |
Character. Plot type for sensemakr engine. One of
|
... |
Additional arguments passed to the plotting function. |
Invisibly returns x. Called for side effects (plots).
if (requireNamespace("sensemakr", quietly = TRUE)) { data("darfur", package = "sensemakr") fit <- lm(peacefactor ~ directlyharmed + age + female + village, data = darfur) res <- run_sensitivity(fit, treatment = "directlyharmed", data = darfur, benchmark_covariates = "female") visualize_sensitivity(res) visualize_sensitivity(res, type = "extreme") }if (requireNamespace("sensemakr", quietly = TRUE)) { data("darfur", package = "sensemakr") fit <- lm(peacefactor ~ directlyharmed + age + female + village, data = darfur) res <- run_sensitivity(fit, treatment = "directlyharmed", data = darfur, benchmark_covariates = "female") visualize_sensitivity(res) visualize_sensitivity(res, type = "extreme") }