Introduction to planning phase II and phase III trials with drugdevelopR

Johannes Cepicka, Lukas D. Sauer

Suppose we are planning a drug development program testing the superiority of an experimental treatment over a control treatment. Our drug development program consists of an exploratory phase II trial which is, in case of promising results, followed by a confirmatory phase III trial.

The drugdevelopR package enables us to optimally plan such programs using a utility-maximizing approach. Specifically, it calculates

The decision rule is the optimal threshold for deciding whether we should proceed to phase III based on the results of phase II. Optimization is performed with respect to a utility function which takes the program’s cost, its success probability and its expected benefit when successfully launching the new drug on the market into account.

But now, let’s get started with a hands-on example.

The example setting

Suppose we are developing a new tumor treatment, exper. The patient variable that we want to investigate is the difference in tumor width between the one-year visit and baseline. This is a normally distributed outcome variable.

Within our drug development program, we will compare our experimental treatment exper to the control treatment contro. Building on available data, we expect that the mean tumor difference amounts to \(20±1 \mathrm{mm}\) for contro and \(15±1 \mathrm{mm}\) for exper. Furthermore, the variance is assumed to be 8. The treatment effect is given as standardized difference in mean (\(\Delta=\frac{\mu_{contro} - \mu_{exper}}{\sigma}\)). Thus, we obtain a standardized treatment difference of \(\Delta_1 = 0.625\).

Applying the package to the example

After installing the package according to the installation instructions, we can load it using the following code:


Defining all necessary parameters

In order to apply the package to the setting from our example, we need to specify the following parameters:

Now that we have defined all parameters needed for our example, we are ready to feed them to the package. We will use the function optimal_normal(), which calculates the optimal sample size and the optimal threshold value for a normally distributed outcome variable.

 res <- optimal_normal(Delta1 = 0.625, fixed = TRUE, # treatment effect
                       n2min = 20, n2max = 400, # sample size region
                       stepn2 = 4, # sample size step size
                       kappamin = 0.02, kappamax = 0.2, # threshold region
                       stepkappa = 0.02, # threshold step size
                       c2 = 0.675, c3 = 0.72, # maximal total trial costs
                       c02 = 15, c03 = 20, # maximal per-patient costs
                       b1 = 3000, b2 = 8000, b3 = 10000, # gains for patients
                       alpha = 0.025, # one-sided significance level
                       beta = 0.1, # 1 - power
                       Delta2 = NULL, w = NULL, in1 = NULL, in2 = NULL, 
                       a = NULL,b = NULL) # setting all unneeded parameters to NULL

Interpreting the output

After setting all these input parameters and running the function, let’s take a look at the output of the program.

#> Optimization result:
#>  Utility: 2946.07
#>  Sample size:
#>    phase II: 92, phase III: 192, total: 284
#>  Probability to go to phase III: 1
#>  Total cost:
#>    phase II: 77, phase III: 158, cost constraint: Inf
#>  Fixed cost:
#>    phase II: 15, phase III: 20
#>  Variable cost per patient:
#>    phase II: 0.675, phase III: 0.72
#>  Effect size categories (expected gains):
#>   small: 0 (3000), medium: 0.5 (8000), large: 0.8 (10000)
#>  Success probability: 0.85
#>  Success probability by effect size:
#>    small: 0.72, medium: 0.12, large: 0
#>  Significance level: 0.025
#>  Targeted power: 0.9
#>  Decision rule threshold: 0.06 [Kappa] 
#>  Assumed true effect: 0.625 [Delta] 
#>  Treatment effect offset between phase II and III: 0 [gamma]

The program returns a total of thirteen values and the input values. For now, we will only look at the most important ones:

Where to go from here

This tutorial only covered drugdevelopR’s basic setting. Luckily, the package’s functionality extends to a multitude of different settings. If the example above doesn’t suit your needs, you can adapt it to your specific setting: