library(BAR)
This vignette provides a step-by-step guidance for applying Bayesian
adaptive randomization with binary outcomes using the package
BAR
.
We first specify the unknown true successful probability (e.g.,
response rate) for each arm. For example, we have three arms with 0.1
for the control arm, 0.5 and 0.8 for two experimental arms, denoted as
success_prob = c(.1, .5, .8)
. We set up a number of
burn-ins for each arm before initiating the adaptive randomization
procedure. During the burn-in period, an equal randomization for each
arm will be employed. Here the number of burn-in is set up to be 10,
denoted as n_burn_in = 10
, that is, 10 * 3 = 30 patients
will be equally randomized to each of three arms. We plan to recruit a
total of 150 patients (including number of burn-ins, that is, the BAR
procedure for each arm will be applied from the \(31^{st}\) patient) into our study and
simulate the trial 100 times, that is, we have
tot_num = 150
and reptime = 100
. The argument
block_size = 1
means that the allocation probability will
be updated for the next one incoming patient. An example with
block_size
\(\neq 1\) is
shown later.
get_oc_BAR(success_prob = c(.1, .5, .8), n_burn_in = 10, tot_num = 150, block_size = 1, reptime = 100, seed = 100)
#> $avg_alloc_prob
#> [1] 0.1060667 0.1567333 0.7372000
#>
#> $avg_pat_num
#> [1] 15.91 23.51 110.58
The above results consist of two parts. The first part
$avg_alloc_prob
is the average allocation probability for
each arm in 100 simulations. The second part $avg_pat_num
is the average number of patients assigned to each arm.
Sometimes we may want to see the updated allocation probability path
after burn-in for each arm for each simulated trial. We can have these
results by setting argument output = "raw"
in the
get_oc_BAR()
function. To save the space of the document,
we only show one trial result here. For example, by setting up
reptime = 1
, we can have the following outputs.
get_oc_BAR(success_prob = c(.1, .5, .8), n_burn_in = 10, tot_num = 150, block_size = 1, reptime = 1, output = "raw", seed = 100)
#> [[1]]
#> [,1] [,2] [,3]
#> [1,] 0.05 0.29417213 0.6558279
#> [2,] 0.05 0.29056441 0.6594356
#> [3,] 0.05 0.28485621 0.6651438
#> [4,] 0.05 0.26630305 0.6836970
#> [5,] 0.05 0.30558834 0.6444117
#> [6,] 0.05 0.27369829 0.6763017
#> [7,] 0.05 0.24469290 0.7053071
#> [8,] 0.05 0.23373574 0.7162643
#> [9,] 0.05 0.21302695 0.7369730
#> [10,] 0.05 0.21755533 0.7324447
#> [11,] 0.05 0.22480667 0.7251933
#> [12,] 0.05 0.19615533 0.7538447
#> [13,] 0.05 0.05000000 0.9000000
#> [14,] 0.05 0.15050135 0.7994987
#> [15,] 0.05 0.13313294 0.8168671
#> [16,] 0.05 0.16191887 0.7880811
#> [17,] 0.05 0.15984912 0.7901509
#> [18,] 0.05 0.05000000 0.9000000
#> [19,] 0.05 0.05000000 0.9000000
#> [20,] 0.05 0.17855715 0.7714428
#> [21,] 0.05 0.14742097 0.8025790
#> [22,] 0.05 0.05000000 0.9000000
#> [23,] 0.05 0.23566767 0.7143323
#> [24,] 0.05 0.25148596 0.6985140
#> [25,] 0.05 0.24505301 0.7049470
#> [26,] 0.05 0.17824156 0.7717584
#> [27,] 0.05 0.19210757 0.7578924
#> [28,] 0.05 0.12418633 0.8258137
#> [29,] 0.05 0.16833557 0.7816644
#> [30,] 0.05 0.15559842 0.7944016
#> [31,] 0.05 0.05000000 0.9000000
#> [32,] 0.05 0.09886214 0.8511379
#> [33,] 0.05 0.11520287 0.8347971
#> [34,] 0.05 0.22920321 0.7207968
#> [35,] 0.05 0.12044338 0.8295566
#> [36,] 0.05 0.21951184 0.7304882
#> [37,] 0.05 0.34037572 0.6096243
#> [38,] 0.05 0.30901511 0.6409849
#> [39,] 0.05 0.28693030 0.6630697
#> [40,] 0.05 0.25672452 0.6932755
#> [41,] 0.05 0.39111066 0.5588893
#> [42,] 0.05 0.20643479 0.7435652
#> [43,] 0.05 0.16465900 0.7853410
#> [44,] 0.05 0.11288808 0.8371119
#> [45,] 0.05 0.11514368 0.8348563
#> [46,] 0.05 0.19631123 0.7536888
#> [47,] 0.05 0.20815433 0.7418457
#> [48,] 0.05 0.26395389 0.6860461
#> [49,] 0.05 0.32108515 0.6289148
#> [50,] 0.05 0.32716271 0.6228373
#> [51,] 0.05 0.12729543 0.8227046
#> [52,] 0.05 0.16071426 0.7892857
#> [53,] 0.05 0.15735178 0.7926482
#> [54,] 0.05 0.22222377 0.7277762
#> [55,] 0.05 0.28098729 0.6690127
#> [56,] 0.05 0.29622333 0.6537767
#> [57,] 0.05 0.34252493 0.6074751
#> [58,] 0.05 0.26292549 0.6870745
#> [59,] 0.05 0.27691776 0.6730822
#> [60,] 0.05 0.05000000 0.9000000
#> [61,] 0.05 0.12695392 0.8230461
#> [62,] 0.05 0.14538937 0.8046106
#> [63,] 0.05 0.09816791 0.8518321
#> [64,] 0.05 0.19808545 0.7519145
#> [65,] 0.05 0.15853283 0.7914672
#> [66,] 0.05 0.23361960 0.7163804
#> [67,] 0.05 0.17458412 0.7754159
#> [68,] 0.05 0.12871114 0.8212889
#> [69,] 0.05 0.19082465 0.7591753
#> [70,] 0.05 0.10311736 0.8468826
#> [71,] 0.05 0.12380251 0.8261975
#> [72,] 0.05 0.12105845 0.8289416
#> [73,] 0.05 0.05000000 0.9000000
#> [74,] 0.05 0.05000000 0.9000000
#> [75,] 0.05 0.05000000 0.9000000
#> [76,] 0.05 0.05000000 0.9000000
#> [77,] 0.05 0.05000000 0.9000000
#> [78,] 0.05 0.05000000 0.9000000
#> [79,] 0.05 0.05000000 0.9000000
#> [80,] 0.05 0.05000000 0.9000000
#> [81,] 0.05 0.05000000 0.9000000
#> [82,] 0.05 0.05000000 0.9000000
#> [83,] 0.05 0.05000000 0.9000000
#> [84,] 0.05 0.05000000 0.9000000
#> [85,] 0.05 0.05000000 0.9000000
#> [86,] 0.05 0.05000000 0.9000000
#> [87,] 0.05 0.05000000 0.9000000
#> [88,] 0.05 0.05000000 0.9000000
#> [89,] 0.05 0.05000000 0.9000000
#> [90,] 0.05 0.05000000 0.9000000
#> [91,] 0.05 0.05000000 0.9000000
#> [92,] 0.05 0.05000000 0.9000000
#> [93,] 0.05 0.05000000 0.9000000
#> [94,] 0.05 0.05000000 0.9000000
#> [95,] 0.05 0.05000000 0.9000000
#> [96,] 0.05 0.05000000 0.9000000
#> [97,] 0.05 0.05000000 0.9000000
#> [98,] 0.05 0.05000000 0.9000000
#> [99,] 0.05 0.05000000 0.9000000
#> [100,] 0.05 0.05000000 0.9000000
#> [101,] 0.05 0.05000000 0.9000000
#> [102,] 0.05 0.05000000 0.9000000
#> [103,] 0.05 0.05000000 0.9000000
#> [104,] 0.05 0.05000000 0.9000000
#> [105,] 0.05 0.05000000 0.9000000
#> [106,] 0.05 0.05000000 0.9000000
#> [107,] 0.05 0.05000000 0.9000000
#> [108,] 0.05 0.05000000 0.9000000
#> [109,] 0.05 0.05000000 0.9000000
#> [110,] 0.05 0.05000000 0.9000000
#> [111,] 0.05 0.05000000 0.9000000
#> [112,] 0.05 0.05000000 0.9000000
#> [113,] 0.05 0.05000000 0.9000000
#> [114,] 0.05 0.05000000 0.9000000
#> [115,] 0.05 0.05000000 0.9000000
#> [116,] 0.05 0.05000000 0.9000000
#> [117,] 0.05 0.05000000 0.9000000
#> [118,] 0.05 0.05000000 0.9000000
#> [119,] 0.05 0.05000000 0.9000000
#> [120,] 0.05 0.05000000 0.9000000
From the result above, since 10 * 3 = 30 sample size has been used in the burn-in period, we therefore have 120 (= 150 - 30) patients in the adaptive randomization period. We can see the updated allocation probabilities for each arm in each step after the burn-in period.
In this package, we also provide users flexibility to allow update
the allocation probability block-wisely by using the
block_size
argument. For example, if
block_size = 1
, it indicates that the assignment of a new
patient depends on the previous patients’ responses to treatment in the
ongoing trial while block_size = 3
, the assignment of next
3 new patients depend on the previous patients’ responses to treatment.
An example is shown as below.
get_oc_BAR(success_prob = c(.1, .5, .8), n_burn_in = 10, tot_num = 150, block_size = 3, reptime = 100, seed = 100)
#> $avg_alloc_prob
#> [1] 0.1046667 0.1786667 0.7166667
#>
#> $avg_pat_num
#> [1] 15.7 26.8 107.5
In this case, the allocation probability will hold constant for the
control arm, which is a usual practice since we want to maintain a good
number for the control such that if we want to conduct hypothesis tests
between experimental and control arms, we can have a desirable power and
results can be interpreted. For this, we can have this argument setting
control_arm = "fixed"
in the function, which will make the
allocation probability of control arm (the first slot) to be fixed to
\(\frac{1}{K}\), where K indicates
total number of arms (including control arm).
get_oc_BAR(success_prob = c(.1, .5, .8), n_burn_in = 10, tot_num = 150, block_size = 1, reptime = 100, control_arm = "fixed", seed = 100)
#> $avg_alloc_prob
#> [1] 0.3321333 0.1346000 0.5332667
#>
#> $avg_pat_num
#> [1] 49.82 20.19 79.99
From the result above, we can see the average allocation probability for control arm is close to 0.33 = \(\frac{1}{K},\) where K = 3 here.
Here, we provide two examples. The first example uses the
power_c
to be \(\frac{n}{2N}\) (this is a default option),
here, N is the pre-planned total sample size and n is the accumulative
sample size when updating the allocation probabilities. In this case, we
need to have N, an example is shown below.
next_allocation_rate_BAR(n = c(20, 25, 30), success_count = c(2, 9, 15), tot_num = 150, power_c = "n/2N")
#> [1] 0.0500000 0.2664958 0.6835042
In this example (outputs shown above), we can see that we have 3 arms (the \(1^{st}\) is control and \(2^{rd}\) and \(3^{nd}\) are experimental arms). The study plans to enroll 150 patients and at the time of updating the allocation probabilities for the next patient, the accrual number of patients for the three arms are 20, 25 and 30 with number of responders of 2, 9, and 15, respectively. By using the BAR algorithm, we can compute the allocation probabilities for these three arms are 0.05, 0.266 and 0.684, respectively.
Another example is that we use the power_c
to be a
numeric, e.g., 0.5. In this case, the N is not required. Even you can
see that there is still a N in the below code, this N is no use and
plays no role in updating the allocation probabilities. Outputs are
shown below and can be interpreted similarly.
next_allocation_rate_BAR(n = c(20, 25, 30), success_count = c(2, 10, 15), tot_num = 150, power_c = .5)
#> [1] 0.0500000 0.1853522 0.7646478