knitr::opts_chunk$set( collapse = TRUE, comment = "#" )
library(PowerTOST) # attach the library
| Parameter | Argument | Purpose | Default |
|-|--|------|--|
| $\small{\alpha}$ | alpha
| Nominal level of the test | 0.025
|
| $\small{\pi}$ | targetpower
| Minimum desired power | 0.80
|
| logscale | logscale
| Analysis on log-transformed or original scale? | TRUE
|
| margin | margin
| Non-inferiority margin | see below |
| $\small{\theta_0}$ | theta0
| ‘True’ or assumed T/R ratio | see below |
| CV | CV
| CV | none |
| design | design
| Planned design | "2x2"
|
| imax | imax
| Maximum number of iterations | 100
|
| print | print
| Show information in the console? | TRUE
|
| details | details
| Show details of the sample size search? | FALSE
|
Note that contrary to the other functions of the package a one-sided t-test (instead of TOST) is employed. Hence, $\small{\alpha}$ defaults to 0.025.\
Defaults depending on the argument logscale
:
| Parameter | Argument | logscale=TRUE
| logscale=FALSE
|
|-|----|:--------:|:--------:|
| margin | margin
| 0.80
| –0.20
|
| $\small{\theta_0}$ | theta0
| 0.95
| +0.05
|
Arguments targetpower
, margin
, theta0
, and CV
have to be given as fractions, not in percent.\
The CV is generally the within- (intra-) subject coefficient of variation. Only for design = "parallel"
it is the total (a.k.a. pooled) CV.
Designs with one (parallel), two (conventional crossover and paired), and three or four periods (replicates) are supported.
# design name df # "parallel" 2 parallel groups n-2 # "2x2" 2x2 crossover n-2 # "2x2x2" 2x2x2 crossover n-2 # "2x2x3" 2x2x3 replicate crossover 2n-3 # "2x2x4" 2x2x4 replicate crossover 3n-4 # "2x4x4" 2x4x4 replicate crossover 3n-4 # "2x3x3" partial replicate (2x3x3) 2n-3 # "2x4x2" Balaam’s (2x4x2) n-2 # "2x2x2r" Liu’s 2x2x2 repeated x-over 3n-2 # "paired" paired means n-1
The terminology of the design
argument follows this pattern: treatments x sequences x periods
. The conventional TR|RT (a.k.a. AB|BA) design can be abbreviated as "2x2"
. Some call the "parallel"
design a ‘one-sequence’ design. The design "paired"
has two periods but no sequences, e.g., in studying linear pharmacokinetics a single dose is followed by multiple doses. A profile in steady state (T) is compared to the one after the single dose (R). Note that the underlying model assumes no period effects.
With sampleN.noninf(..., details = FALSE, print = FALSE)
results are provided as a data frame ^[R Documentation. Data Frames. 2020-10-26. R-manual.] with eight columns Design
, alpha
, CV
, theta0
, Margin
, Sample size
, Achieved power
, and Target power
. To access e.g., the sample size use either sampleN.noninf[1, 6]
or sampleN.noninf[["Sample size"]]
. We suggest to use the latter in scripts for clarity.
The estimated sample size gives always the total number of subjects (not subject/sequence in crossovers or subjects/group in parallel designs – like in some other software packages).
If the supplied margin is < 1 (logscale = TRUE
) or < 0 (logscale = FALSE
), then it is assumed that higher response values are better. The hypotheses are with
logscale = TRUE
$$\small{H_0:\theta_0 \leq \log({margin})\:vs\:H_1:\theta_0>\log({margin})}$$
where $\small{\theta_0=\mu_\textrm{T}/\mu_\textrm{R}}$
logscale = FALSE
$$\small{H_0:\theta_0 \leq {margin}\:vs\:H_1:\theta_0>{margin}}$$
where $\small{\theta_0=\mu_T-\mu_R}$
Estimate the sample size for assumed intra-subject CV 0.25. Defaults margin
0.80 and $\small{\theta_{0}}$ 0.95 employed.
sampleN.noninf(CV = 0.25)
To get only the sample size:
sampleN.noninf(CV = 0.25, details = FALSE, print = FALSE)[["Sample size"]]
Note that the sample size is always rounded up to give balanced sequences (here a multiple of two). Since power is higher than our target, likely this was the case here. Let us assess that:\ Which power will we get with a sample size of 35?
power.noninf(CV = 0.25, n = 35)
Confirmed that with 35 subjects we will already reach the target power. That means also that one dropout will not compromise power.
If the supplied margin is > 1 (logscale = TRUE
) or > 0 (logscale = FALSE
), then it is assumed that lower response values are better. The hypotheses are with
logscale = TRUE
$$\small{H_{0}:\theta_0 \geq \log({margin})\:vs\:H_{1}:\theta_0<\log({margin})}$$
where $\small{\theta_0=\mu_\textrm{T}/\mu_\textrm{R}}$
logscale = FALSE
$$\small{H_{0}:\theta_0 \geq {margin}\:vs\:H_{1}:\theta_0<{margin}}$$
where $\small{\theta_0=\mu_T-\mu_R}$
Estimate the sample size for assumed intra-subject CV 0.25.
sampleN.noninf(CV = 0.25, margin = 1.25, theta0 = 1/0.95)
Same sample size like in example 1 since reciprocal values of both margin
0.80 and $\small{\theta_{0}}$ are specified.
Compare a new modified release formulation (regimen once a day) with an intermediate release formulation (twice a day).^[European Medicines Agency, Committee for Medicinal Products for Human Use. Guideline on the pharmacokinetic and clinical evaluation of modified release dosage forms. London. 20 November 2014. EMA/CPMP/EWP/280/96 Corr1. online.] C~min~ is the target metric for efficacy (non-inferiority) and C~max~ for safety (non-superiority). Margins are 0.80 for C~min~ and 1.25 for C~max~. CVs are 0.35 for C~min~ and 0.20 for C~max~; $\small{\theta_{0}}$ 0.95 for C~min~ and 1.05 for C~max~. Full replicate design due to the high variability of C~min~.\ Which PK metric leads the sample size?
res <- data.frame(design = "2x2x4", metric = c("Cmin", "Cmax"), margin = c(0.80, 1.25), CV = c(0.35, 0.20), theta0 = c(0.95, 1.05), n = NA, power = NA, stringsAsFactors = FALSE) # this line for R <4.0.0) for (i in 1:2) { res[i, 6:7] <- sampleN.noninf(design = res$design[i], margin = res$margin[i], theta0 = res$theta0[i], CV = res$CV[i], details = FALSE, print = FALSE)[6:7] } print(res, row.names = FALSE)
The sample size depends on C~min~. Hence, the study is ‘overpowered’ for C~max~.
power.noninf(design = "2x2x4", margin = 1.25, CV = 0.20, theta0 = 1.05, n = 32)
Therefore, that gives us some ‘safety margin’ for C~max~.
power.noninf(design = "2x2x4", margin = 1.25, CV = 0.25, theta0 = 1.10, n = 32) # higher CV, worse theta0
The bracketing approach does not necessarily give lower sample sizes than tests for equivalence. In this example we could aim at reference-scaling for the highly variable C~min~ and at conventional ABE for C~max~.
res <- data.frame(design = "2x2x4", intended = c("ABEL", "ABE"), metric = c("Cmin", "Cmax"), CV = c(0.35, 0.20), theta0 = c(0.90, 1.05), n = NA, power = NA, stringsAsFactors = FALSE) # this line for R <4.0.0 res[1, 6:7] <- sampleN.scABEL(CV = res$CV[1], theta0 = res$theta0[1], design = res$design[1], print = FALSE, details = FALSE)[8:9] res[2, 6:7] <- sampleN.TOST(CV = res$CV[2], theta0 = res$theta0[2], design = res$design[2], print = FALSE, details = FALSE)[7:8] print(res, row.names = FALSE)
Which method is optimal is a case-to-case decision. Although in this example the bracketing approach seems to be the ‘winner’ (32 subjects instead of 34), we might fail if the CV of C~min~ is larger than assumed, whereas in reference-scaling we might still pass due to the expanded limits.
n <- sampleN.scABEL(CV = 0.35, theta0 = 0.90, design = "2x2x4", print = FALSE, details = FALSE)[["Sample size"]] # CV and theta0 of both metrics worse than assumed res <- data.frame(design = "2x2x4", intended = c("ABEL", "ABE"), metric = c("Cmin", "Cmax"), CV = c(0.50, 0.25), theta0 = c(0.88, 1.12), n = n, power = NA, stringsAsFactors = FALSE) # this line for R <4.0.0 res[1, 7] <- power.scABEL(CV = res$CV[1], theta0 = res$theta0[1], design = res$design[1], n = n) res[2, 7] <- power.TOST(CV = res$CV[2], theta0 = res$theta0[2], design = res$design[2], n = n) print(res, row.names = FALSE)
See also the vignettes RSABE, ABE, and PA.
Detlew Labes
r Sys.Date()
Helmut SchützAdd the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.