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 
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 ^{1} 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.
< function(lowest, levels) {
mod.fibo # modified Fibonacci doseescalation
< c(2, 1 + 2/3, 1.5, 1 + 1/3)
fib < numeric(levels)
doses 1] < lowest
doses[< 2
level repeat {
if (level <= 4) {
< doses[level1] * fib[level1]
doses[level] else { # ratio 1.33 for all higher doses
} < doses[level1] * fib[4]
doses[level]
}< level + 1
level if (level > levels) {
break
}
}return(signif(doses, 3))
}< 10
lowest < 3
levels < mod.fibo(lowest, levels)
doses sampleN.dp(CV = 0.20, doses = doses, beta0 = 1.02)
#
# ++++ Dose proportionality study, power model ++++
# Sample size estimation
# 
# Study design: crossover (3x3 Latin square)
# alpha = 0.05, target power = 0.8
# Equivalence margins of R(dnm) = 0.8 ... 1.25
# Doses = 10 20 33.3
# True slope = 1.02, CV = 0.2
# Slope acceptance range = 0.81451 ... 1.1855
#
# Sample size (total)
# n power
# 15 0.808127
As above but with an additional level.
< 4
levels < mod.fibo(lowest, levels)
doses < sampleN.dp(CV = 0.20, doses = doses, beta0 = 1.02) # we need the data.frame later
x #
# ++++ Dose proportionality study, power model ++++
# Sample size estimation
# 
# Study design: crossover (4x4 Latin square)
# alpha = 0.05, target power = 0.8
# Equivalence margins of R(dnm) = 0.8 ... 1.25
# Doses = 10 20 33.3 50
# True slope = 1.02, CV = 0.2
# Slope acceptance range = 0.86135 ... 1.1386
#
# Sample size (total)
# n power
# 16 0.867441
Note that with the wider dose range the acceptance range narrows.
Explore the impact of dropouts.
< data.frame(n = seq(x[["Sample size"]], 12, 1), power = NA)
res for (i in 1:nrow(res)) {
$power[i] < signif(suppressMessages(
respower.dp(CV = 0.20, doses = doses,
beta0 = 1.02, n = res$n[i])), 5)
}< res[res$power >= 0.80, ]
res print(res, row.names = FALSE)
# n power
# 16 0.86744
# 15 0.82914
# 14 0.81935
# 13 0.81516
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
.
< 5
levels < mod.fibo(lowest, levels)
doses < 3
per < levels*(levels1)/(per1)
block < crossdes::balmin.RMD(levels, block, per)
dm < sampleN.dp(CV = 0.20, doses = doses, beta0 = 1.02,
x design = "IBD", dm = dm)
#
# ++++ Dose proportionality study, power model ++++
# Sample size estimation
# 
# Study design: IBD (5x10x3)
# alpha = 0.05, target power = 0.8
# Equivalence margins of R(dnm) = 0.8 ... 1.25
# Doses = 10 20 33.3 50 66.7
# True slope = 1.02, CV = 0.2, CVb = 0.4
# Slope acceptance range = 0.88241 ... 1.1176
#
# Sample size (total)
# n power
# 30 0.898758
The IBD comes with a price since we need at least two blocks.
< data.frame(n = seq(x[["Sample size"]], nrow(dm), 1),
res power = NA)
for (i in 1:nrow(res)) {
$power[i] < signif(suppressMessages(
respower.dp(CV = 0.20, doses = doses,
beta0 = 1.02, design = "IBD",
dm = dm, n = res$n[i])), 5)
}< res[res$power >= 0.80, ]
res print(res, row.names = FALSE)
# n power
# 30 0.89876
# 29 0.89196
# 28 0.87939
# 27 0.87201
# 26 0.85793
# 25 0.83587
# 24 0.82470
# 23 0.80405
Again, we don’t have to worry about dropouts.
For a wide dose range the acceptance range narrows and becomes increasingly difficult to meet.
< 2^(seq(0, 8, 2))
doses < length(doses)
levels sampleN.dp(CV = 0.30, doses = doses, beta0 = 1.02,
design = "crossover")
#
# ++++ Dose proportionality study, power model ++++
# Sample size estimation
# 
# Study design: crossover (5x5 Latin square)
# alpha = 0.05, target power = 0.8
# Equivalence margins of R(dnm) = 0.8 ... 1.25
# Doses = 1 4 16 64 256
# True slope = 1.02, CV = 0.3
# Slope acceptance range = 0.95976 ... 1.0402
#
# Sample size (total)
# n power
# 70 0.809991
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)
#
# ++++ Dose proportionality study, power model ++++
# Sample size estimation
# 
# Study design: crossover (5x5 Latin square)
# alpha = 0.05, target power = 0.8
# Equivalence margins of R(dnm) = 0.75 ... 1.333333
# Doses = 1 4 16 64 256
# True slope = 1.02, CV = 0.3
# Slope acceptance range = 0.94812 ... 1.0519
#
# Sample size (total)
# n power
# 30 0.828246
Hummel et al. ^{2} 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.
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): 38–49. doi:10.1002/pst.326.↩︎