This vignette shows the basic
workflow for cdtmbnma. The example is the sacubitril and
valsartan sitting systolic blood-pressure dose plane. Each row is one
arm. d_sac and d_val are component dose
columns; zero means absent.
library(cdtmbnma)
sv <- sacval_example()
head(sv)
#> study arm d_sac d_val n y sd se
#> 1 Izzo Izzo_placebo 0 0 57 -7.00 22.40 2.966952
#> 2 Izzo Izzo_valsartan320 0 320 143 -16.10 22.20 1.856457
#> 3 Izzo Izzo_freeSac50_Val320 50 320 132 -19.35 14.62 1.272508
#> 4 Izzo Izzo_freeSac100_Val320 100 320 141 -21.26 14.52 1.222805
#> 5 Izzo Izzo_freeSac200_Val320 200 320 144 -23.64 14.81 1.234167
#> 6 Izzo Izzo_freeSac400_Val320 400 320 143 -20.95 14.73 1.231784
#> sd_source
#> 1 imputed (per-study median)
#> 2 reported/NMA-table
#> 3 derived from LS-mean SE (sensitivity)
#> 4 derived from LS-mean SE (sensitivity)
#> 5 derived from LS-mean SE (sensitivity)
#> 6 derived from LS-mean SE (sensitivity)cdt_data() turns the arm-level table into the model
design. Studies with an all-zero arm use that arm as the within-study
reference. Studies without an all-zero arm use their lowest-total-dose
arm as the baseline and issue a warning.
d <- cdt_data(
sv,
study = "study",
components = c("d_sac", "d_val"),
outcome = "continuous",
y = "y",
se = "se",
dstar = c(d_sac = 200, d_val = 320)
)
#> Warning: Study 'Cheung' has no all-zero arm; using its lowest-total-dose arm as
#> baseline.
#> Warning: Study 'Huo' has no all-zero arm; using its lowest-total-dose arm as
#> baseline.
#> Warning: Study 'Rakugi' has no all-zero arm; using its lowest-total-dose arm as
#> baseline.
#> Warning: Study 'Ruilope' has no all-zero arm; using its lowest-total-dose arm
#> as baseline.
d
#> <cdt_data>
#> arms: 18 across 5 studies
#> components: d_sac, d_val
#> outcome: continuous
#> interaction pairs: d_sac x d_valcdt_fit() compiles the Stan model on first use and
samples. The bilinear interaction parameter is interpreted at the
dstar corner: here, sacubitril 200 mg and valsartan 320
mg.
fit <- cdt_fit(
d,
interaction = "bilinear",
chains = 4,
iter_warmup = 1000,
iter_sampling = 1000,
seed = 1
)
summary(fit)
#> variable mean sd 2.5% 97.5%
#> 1 emax: d_sac -10.873789 4.4902883 -21.138062 -3.613413
#> 2 emax: d_val -16.799202 4.4574411 -25.498066 -7.646193
#> 3 interaction: d_sac x d_val 1.668438 2.0804147 -2.356954 5.769118
#> 4 omega 2.679341 0.7409213 1.477284 4.325007
#> 5 ED50: d_sac 72.694478 55.3874434 10.102404 206.487855
#> 6 ED50: d_val 132.608041 72.6750655 36.047003 312.716574
#> rhat ess_bulk
#> 1 1.001257 2441.782
#> 2 1.001892 2034.533
#> 3 1.000637 2396.622
#> 4 1.001502 1815.534
#> 5 1.000063 3286.171
#> 6 1.001904 2972.049The marginal component curves vary one component at a time while holding the other at zero.
plot(fit)
#> Warning: Dropping 'draws_df' class as required metadata was removed.
#> Warning: Dropping 'draws_df' class as required metadata was removed.predict() returns the relative effect against the
all-zero reference at any component-dose combination, including dose
pairs not directly observed in a trial.
predict(fit, newdata = data.frame(d_sac = 100, d_val = 160))
#> Warning: Dropping 'draws_df' class as required metadata was removed.
#> Warning: Dropping 'draws_df' class as required metadata was removed.
#> Warning: Dropping 'draws_df' class as required metadata was removed.
#> d_sac d_val mean sd 2.5% 97.5%
#> 1 100 160 -15.36185 2.303096 -19.93087 -10.82761The additive model is fitted by setting
interaction = "none".
If the loo package is installed, the pointwise log
likelihood stored in Stan’s generated quantities can be used for
information-criterion comparisons.
The package also contains a narrower two-component longitudinal interface. It is useful when repeated arm means over time are available and an exponential approach-to-asymptote is reasonable. The example below builds a small design but does not fit it during vignette building.
long_dat <- data.frame(
study = rep("trial1", 6),
arm = rep(c("placebo", "A", "AB"), each = 2),
week = rep(c(4, 8), 3),
dose_A = rep(c(0, 10, 10), each = 2),
dose_B = rep(c(0, 0, 20), each = 2),
y = c(0, 0, -1, -2, -2, -3),
se = rep(1, 6)
)
time_design <- cdt_time_data(
long_dat,
study = "study",
arm = "arm",
time = "week",
components = c("dose_A", "dose_B"),
y = "y",
se = "se",
dstar = c(dose_A = 10, dose_B = 20)
)
time_design
#> <cdt_time_data>
#> observations: 6
#> arms: 3 across 1 studies
#> components: dose_A, dose_B
#> model: two-component exponential time-course with bilinear interaction