FragiliTidy provides
fast, tidyverse-friendly implementations of fragility metrics for
two-arm clinical trials:
library(FragiliTidy)
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
library(tibble)trials <- tribble(
~study, ~ie, ~ce, ~in_, ~cn,
"Trial A", 10, 20, 100, 100,
"Trial B", 5, 15, 80, 80,
"Trial C", 30, 30, 200, 200
)
trials |>
fragility_index(ie, ce, in_, cn) |>
revfragility_index(ie, ce, in_, cn)
#> # A tibble: 3 × 7
#> study ie ce in_ cn fragility_index revfragility_index
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Trial A 10 20 100 100 0 1
#> 2 Trial B 5 15 80 80 1 0
#> 3 Trial C 30 30 200 200 0 8When raw per-patient outcomes are not available, the CFI is estimated
by simulating compatible datasets via rejection sampling and averaging
the iterative substitution result over n_sim simulations
(Caldwell et al., 2021):
For non-significant trials, the reverse CFI estimates how many additional participants per arm would have been required to reach significance, given the observed effect size and variance:
Both CFI variants integrate into dplyr pipelines:
trials_continuous <- tribble(
~study, ~m1, ~s1, ~k1, ~m2, ~s2, ~k2,
"Trial X", 70, 10, 50, 50, 10, 50,
"Trial Y", 60, 15, 40, 55, 15, 40
)
trials_continuous |>
continuous_fragility_index(m1, s1, k1, m2, s2, k2) |>
reverse_continuous_fragility_index(m1, s1, k1, m2, s2, k2)
#> # A tibble: 2 × 9
#> study m1 s1 k1 m2 s2 k2 continuous_fragility_index
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Trial X 70 10 50 50 10 50 29.2
#> 2 Trial Y 60 15 40 55 15 40 0
#> # ℹ 1 more variable: reverse_continuous_fragility_index <dbl>