# Hierarchical Bayesian model for binary responses

Thall et al. (2003) described a method for analysing treatment effects of a common intervention in several sub-types of a single disease. The treatment effects are assumed to be different but exchangeable and correlated. Observing good efficacy in one cohort, for example, increases one’s expectations of efficacy in other cohorts.

They demonstrate the hierarchical model in a trial with binary response outcomes and in another with time-to-event outcomes. This vignette describes the sarcoma example with binary response outcomes. The authors provide WinBUGS code in the appendix of their paper (Thall et al. 2003). We port their model to Stan and illustrate usage with the example given in their paper.

# Implementation in trialr

Statistically, the authors assume that in a trial of $$k$$ disease subtypes, the treatment effects are drawn from the same common normal distribution

$$\rho_1, ..., \rho_k \sim N(\mu, \sigma^2)$$

As is the convention in BUGS, the authors define normal distributions by a precision parameter $$\tau$$ as opposed to the standard deviation parameter $$\sigma$$ used here. We have re-specified the model to comply with the Stan convention of using standard deviation. The authors use a normal hyperprior on $$\mu$$, and a gamma hyperprior on $$\tau$$, equivalent to an inverse gamma hyperprior on $$\sigma^2$$.

We observe $$x_i$$ responses in $$n_i$$ patients in disease sub-type $$i$$. The rate of response in subtype $$i$$ is modelled as $$p_i = \text{logit}^{-1}(\rho_i)$$. Each $$x_i$$ is assumed to be binomially distributed with success parameter $$p_i$$. In Stan, that relationship is described as x ~ binomial_logit(n, rho);

The treatment is judged to be worthy of further investigation in cohort $$i$$ if

$$\text{Pr}\left\{ p_i > \theta | \mathcal{D} \right\} > q$$

where $$\theta$$ is the minimum required response rate, and $$q$$ is the required certainty to approve. In their provided example, Thall et al. (2003) use $$\theta = 0.3$$.

# Example

library(trialr)

We reproduce Thall etl al.’s example. We have outcomes in 10 disease subgroups. The number of responses is stored in group_responses and the number of patients in group_sizes. There have been 3 / 7 responses in subgroup 4, for example, but 0 / 2 responses in subgroup 2, and zero patients treated at all in subgroups 1, 6 and 10.

fit <- stan_hierarchical_response_thall(
group_responses = c(0, 0, 1, 3, 5, 0, 1, 2, 0, 0),
group_sizes = c(0, 2 ,1, 7, 5, 0, 2, 3, 1, 0),
mu_mean = -1.3863,
mu_sd = sqrt(1 / 0.1),
tau_alpha = 2,
tau_beta = 20)
fit
## Inference for Stan model: ThallHierarchicalBinary.
## 4 chains, each with iter=2000; warmup=1000; thin=1;
## post-warmup draws per chain=1000, total post-warmup draws=4000.
##
##                     mean se_mean    sd   2.5%    25%    50%    75%  97.5%
## mu                 -0.03    0.03  1.41  -2.91  -0.88  -0.04   0.85   2.72
## sigma2             12.71    0.41 11.63   3.29   6.31   9.51  15.07  41.10
## rho             -0.13    0.07  3.92  -8.52  -2.26  -0.06   2.20   7.31
## rho             -3.01    0.07  2.65  -9.83  -4.18  -2.52  -1.26   0.80
## rho              2.35    0.06  2.77  -1.88   0.55   1.92   3.74   8.96
## rho             -0.32    0.01  0.81  -1.95  -0.83  -0.31   0.22   1.30
## rho              3.76    0.06  2.44   0.55   2.12   3.25   4.88   9.89
## rho              0.02    0.07  3.89  -7.92  -2.32   0.08   2.34   7.63
## rho             -0.01    0.02  1.52  -3.13  -0.96  -0.01   0.95   2.99
## rho              0.78    0.02  1.33  -1.70  -0.13   0.73   1.62   3.65
## rho             -2.35    0.06  2.74  -9.10  -3.72  -1.98  -0.52   1.95
## rho            -0.05    0.07  3.89  -8.15  -2.25  -0.06   2.28   7.58
## sigma               3.35    0.04  1.22   1.81   2.51   3.08   3.88   6.41
## prob_response    0.50    0.01  0.38   0.00   0.09   0.49   0.90   1.00
## prob_response    0.15    0.00  0.19   0.00   0.02   0.07   0.22   0.69
## prob_response    0.77    0.00  0.26   0.13   0.63   0.87   0.98   1.00
## prob_response    0.43    0.00  0.17   0.12   0.30   0.42   0.56   0.79
## prob_response    0.92    0.00  0.10   0.63   0.89   0.96   0.99   1.00
## prob_response    0.51    0.01  0.38   0.00   0.09   0.52   0.91   1.00
## prob_response    0.50    0.00  0.26   0.04   0.28   0.50   0.72   0.95
## prob_response    0.64    0.00  0.23   0.15   0.47   0.67   0.84   0.97
## prob_response    0.23    0.00  0.26   0.00   0.02   0.12   0.37   0.88
## prob_response   0.50    0.01  0.38   0.00   0.10   0.48   0.91   1.00
## lp__              -34.48    0.14  3.74 -43.47 -36.58 -34.04 -31.72 -28.79
##                   n_eff Rhat
## mu                 2244 1.00
## sigma2              801 1.01
## rho             3070 1.00
## rho             1359 1.00
## rho             1924 1.00
## rho             3931 1.00
## rho             1694 1.00
## rho             2842 1.00
## rho             4528 1.00
## rho             4437 1.00
## rho             1832 1.00
## rho            3475 1.00
## sigma               859 1.01
## prob_response   3601 1.00
## prob_response   4093 1.00
## prob_response   4602 1.00
## prob_response   4038 1.00
## prob_response   3955 1.00
## prob_response   3339 1.00
## prob_response   4884 1.00
## prob_response   5027 1.00
## prob_response   3233 1.00
## prob_response  3718 1.00
## lp__                762 1.01
##
## Samples were drawn using NUTS(diag_e) at Tue Jun 25 08:39:05 2019.
## For each parameter, n_eff is a crude measure of effective sample size,
## and Rhat is the potential scale reduction factor on split chains (at
## convergence, Rhat=1).

The probability of response in each subgroup is calculated under prob_response. We can use the generic summary function from rstan to get a nice summary:

knitr::kable(rstan::summary(fit, par = 'prob_response')\$summary, digits = 3)
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
prob_response 0.495 0.006 0.380 0.000 0.094 0.486 0.900 0.999 3600.922 1.001
prob_response 0.151 0.003 0.185 0.000 0.015 0.074 0.221 0.690 4092.877 1.000
prob_response 0.769 0.004 0.256 0.132 0.634 0.872 0.977 1.000 4602.163 0.999
prob_response 0.431 0.003 0.174 0.125 0.303 0.423 0.555 0.786 4038.138 1.001
prob_response 0.922 0.002 0.102 0.633 0.893 0.963 0.992 1.000 3955.083 1.000
prob_response 0.505 0.007 0.384 0.000 0.089 0.520 0.912 1.000 3338.923 1.001
prob_response 0.498 0.004 0.265 0.042 0.277 0.498 0.721 0.952 4883.575 1.000
prob_response 0.639 0.003 0.231 0.154 0.468 0.675 0.835 0.975 5027.361 1.001
prob_response 0.232 0.005 0.259 0.000 0.024 0.122 0.373 0.875 3233.169 1.001
prob_response 0.497 0.006 0.381 0.000 0.096 0.484 0.907 0.999 3717.999 1.000

Let us say that we are willing to approve the treatment for further study in a subgroup if we have at least $$q = 70$$% certainty that the probability of efficacy exceeds the target response rate of 30%.

colMeans(as.data.frame(fit, pars = 'prob_response') > 0.3)
##  prob_response  prob_response  prob_response  prob_response
##           0.59450           0.17800           0.91850           0.75600
##  prob_response  prob_response  prob_response  prob_response
##           0.99950           0.60225           0.72575           0.90125
##  prob_response prob_response
##           0.30700           0.59575

On that basis, at this interim stage, we would be eager to approve the treatment in subgroups 3, 5 and 8. Subgroups 4 and 7 are close to the boundary.

Some distribution plots of the probabilities of efficacy in some subgroups may be informative.

library(ggplot2)
library(rstan)
library(dplyr)

plot(fit, pars = 'prob_response') +
geom_vline(xintercept = 0.3, col = 'orange', linetype = 'dashed') +
labs(title = 'Partially-pooled analysis of response rate in 10 sarcoma subtypes') Prob(Response | D) in subgroup 3

We see that the inferred efficacy in subgroup 5 is very high. In contrast, efficacy is subject to more uncertainty in subgroup 4, but the majority of the mass clearly lies to the right of 30%.

# trialr

trialr is available at https://github.com/brockk/trialr and https://CRAN.R-project.org/package=trialr