The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Component-dose network meta-analysis with dose-dependent interactions

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)

Building the single-timepoint design

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_val

Fitting the bilinear interaction model

cdt_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
)
#> Running MCMC with 4 parallel chains...
#> Chain 1 Informational Message: The current Metropolis proposal is about to be rejected because of the following issue:
#> Chain 1 Exception: normal_lpdf: Location parameter[2] is -inf, but must be finite! (in '/tmp/RtmpKcYyi0/model-23f73c17463052.stan', line 97, column 4 to column 23)
#> Chain 1 If this warning occurs sporadically, such as for highly constrained variable types like covariance matrices, then the sampler is fine,
#> Chain 1 but if this warning occurs often then your model may be either severely ill-conditioned or misspecified.
#> Chain 1
#> Chain 1 finished in 0.5 seconds.
#> Chain 2 finished in 0.6 seconds.
#> Chain 3 finished in 0.5 seconds.
#> Chain 4 finished in 0.5 seconds.
#> 
#> All 4 chains finished successfully.
#> Mean chain execution time: 0.5 seconds.
#> Total execution time: 0.7 seconds.
summary(fit)
#>                     variable       mean         sd       2.5%      97.5%
#> 1                emax: d_sac -10.958955  4.4289041 -20.981215  -3.790150
#> 2                emax: d_val -16.797890  4.5391811 -25.698727  -7.735944
#> 3 interaction: d_sac x d_val   1.682457  2.0916998  -2.358932   5.732784
#> 4                      omega   2.685903  0.7441266   1.455292   4.363215
#> 5                ED50: d_sac  72.783504 56.4619799  10.421806 211.643737
#> 6                ED50: d_val 134.180238 76.7936804  31.804358 322.117577
#>        rhat ess_bulk
#> 1 1.0013255 2301.701
#> 2 1.0014045 1881.681
#> 3 1.0013801 2279.402
#> 4 0.9998781 1710.026
#> 5 1.0007031 3259.655
#> 6 1.0016402 2740.434

The 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.

Prediction at an unobserved dose pair

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.40289 2.383413 -19.99665 -10.81706

Additive benchmark

The additive model is fitted by setting interaction = "none".

fit_add <- cdt_fit(d, 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.

loo::loo_compare(
  loo::loo(fit$fit$draws("log_lik")),
  loo::loo(fit_add$fit$draws("log_lik"))
)

Stage-one longitudinal model

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
fit_time <- cdt_time_fit(time_design)
predict(fit_time, data.frame(dose_A = 10, dose_B = 20))

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.