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

 CV  CV
 CV  none 
 doses  doses
 Vector of doses  see examples 
 $\small{\pi}$  targetpower
 Minimum desired power  0.80

 $\small{\beta_0}$  beta0
 ‘True’ or assumed slope of the power model  see below 
 $\small{\theta_1}$  theta1
 Lower limit for the ratio of dose normalized means Rdmn  see below 
 $\small{\theta_2}$  theta2
 Upper limit for the ratio of dose normalized means Rdmn  see below 
 design  design
 Planned design  "crossover"

 dm  dm
 Design matrix  NULL

 CV~b~  CVb
 Coefficient of variation of the betweensubject variability  – 
 print  print
 Show information in the console?  TRUE

 details  details
 Show details of the sample size search?  FALSE

 imax  imax
 Maximum number of iterations  100

Arguments targetpower
, theta1
, theta2
, 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. The between (intra) subject coefficient of variation CV~b~ is only necessary if design = "IBD"
(if missing, it will be set to 2*CV
).
The ‘true’ or assumed slope of the power model $\small{\beta_0}$ defaults to 1+log(0.95)/log(rd)
, where rd
is the ratio of the highest/lowest dose.
Supported designs are "crossover"
(default; Latin Squares), "parallel"
, and "IBD"
(incomplete block design). Note that when "crossover"
is chosen, instead of Latin Squares any Williams’ design could be used as well (identical degrees of freedom result in the same sample size).
With sampleN.dp(..., details = FALSE, print = FALSE)
results are provided as a data frame ^[R Documentation. Data Frames. 20220208. Rmanual.] with ten (design = "crossover"
) or eleven (design = "parallel"
or design = "IBD"
) columns: Design
, alpha
, CV
, (CVb
,) doses
, beta0
, theta1
, theta2
, Sample size
, Achieved power
, and Target power
. To access e.g., the sample size use sampleN.dp[["Sample size"]]
.
The estimated sample size gives always the total number of subjects (not subject/sequence in crossovers or subjects/group in a parallel design – like in some other software packages).
Estimate the sample size for a modified Fibonacci doseescalation study, lowest dose 10, three levels. Assumed CV 0.20 and $\small{\beta_0}$ slightly higher than 1. Defaults employed.
mod.fibo < function(lowest, levels) { # modified Fibonacci doseescalation fib < c(2, 1 + 2/3, 1.5, 1 + 1/3) doses < numeric(levels) doses[1] < lowest level < 2 repeat { if (level <= 4) { doses[level] < doses[level1] * fib[level1] } else { # ratio 1.33 for all higher doses doses[level] < doses[level1] * fib[4] } level < level + 1 if (level > levels) { break } } return(signif(doses, 3)) } lowest < 10 levels < 3 doses < mod.fibo(lowest, levels) sampleN.dp(CV = 0.20, doses = doses, beta0 = 1.02)
As above but with an additional level.
levels < 4 doses < mod.fibo(lowest, levels) x < sampleN.dp(CV = 0.20, doses = doses, beta0 = 1.02) # we need the data.frame later
Note that with the wider dose range the acceptance range narrows.
Explore the impact of dropouts.
res < data.frame(n = seq(x[["Sample size"]], 12, 1), power = NA) for (i in 1:nrow(res)) { res$power[i] < signif(suppressMessages( power.dp(CV = 0.20, doses = doses, beta0 = 1.02, n = res$n[i])), 5) } res < res[res$power >= 0.80, ] print(res, row.names = FALSE)
As usual nothing to worry about.
Rather extreme: Five levels and we desire only three periods. Hence, we opt for an incomplete block design. The design matrix of a balanced minimal repeated measurements design is obtained by the function balmin.RMD()
of package crossdes
.
levels < 5 doses < mod.fibo(lowest, levels) per < 3 block < levels*(levels1)/(per1) dm < crossdes::balmin.RMD(levels, block, per) x < sampleN.dp(CV = 0.20, doses = doses, beta0 = 1.02, design = "IBD", dm = dm)
The IBD comes with a price since we need at least two blocks.
res < data.frame(n = seq(x[["Sample size"]], nrow(dm), 1), power = NA) for (i in 1:nrow(res)) { res$power[i] < signif(suppressMessages( power.dp(CV = 0.20, doses = doses, beta0 = 1.02, design = "IBD", dm = dm, n = res$n[i])), 5) } res < res[res$power >= 0.80, ] print(res, row.names = FALSE)
Again, we don’t have to worry about dropouts.
For a wide dose range the acceptance range narrows and becomes increasingly difficult to meet.
doses < 2^(seq(0, 8, 2)) levels < length(doses) sampleN.dp(CV = 0.30, doses = doses, beta0 = 1.02, design = "crossover")
In an exploratory setting more liberal limits could be specified (only one has to be specified; the other is calculated as the reciprocal of it).
sampleN.dp(CV = 0.30, doses = doses, beta0 = 1.02, design = "crossover", theta1 = 0.75)
Hummel et al. ^[Hummel J, McKendrick S, Brindley C, French R. Exploratory assessment of dose proportionality: review of current approaches and proposal for a practical criterion. Pharm. Stat. 2009; 8(1): 3849. doi:10.1002/pst.326.] proposed even more liberal $\small{\theta_{1},\theta_{2}}$ of {0.50, 2.0}.
There is no guarantee that a desired incomplete block design (for given dose levels and number of periods) can be constructed. If you provide your own design matrix (in the argument dm
) it is not assessed for meaningfulness.
Detlew Labes
r Sys.Date()
Helmut SchützAny scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.