Power of 2 independent TOSTs ≈ 2 simultaneous TOSTs with ρ=0 [Power / Sample Size]

Hi libaiyi,

» And it could not be simplified as Overall power = (power of AUC0 * power of Cmax) to decrease power needed of each for the lack of ρ?

For two tests, it could.
Try this (conventional BE-limits, T/R-ratio 0.95, target power 0.8, 2×2×2 crossover):

library(PowerTOST)
CV1      <- 0.3 # Cmax
CV2      <- 0.2 # AUC0-t
n1       <- sampleN.TOST(CV=CV1, print=FALSE)[["Sample size"]]
n2       <- sampleN.TOST(CV=CV2, print=FALSE)[["Sample size"]]
n        <- max(n1, n2)
rho.min  <- 0.25
rho.max  <- 0.75
rho.step <- 0.25
rho      <- c(1-.Machine$double.eps, seq(rho.max, rho.min, -rho.step), .Machine$double.eps)
pwr0.1   <- power.TOST(CV=CV1, n=n)
pwr0.2   <- power.TOST(CV=CV2, n=n)
pwr1     <- numeric(length(rho))
res1     <- character(length(rho))
f        <- "%.4f"
for (j in seq_along(rho)) {
pwr1[j] <- power.2TOST(CV=c(CV1, CV2), n=n, rho=rho[j], nsims=nsims)
res1[j] <- paste0("\n  rho = ", sprintf(f, rho[j]), ": ",
sprintf(f, pwr1[j]))
}
res0     <- paste0("\nCV1: ", sprintf(f, CV1), ", CV2: ", sprintf(f, CV2),
"\nSample size based on max(CV1, CV2) = ", sprintf(f, max(CV1, CV2)), ": ", n,
"\nPower for two independent TOSTs",
"\n  PK metric with CV  = ", sprintf(f, CV1), ": ", sprintf(f, pwr0.1),
"\n  PK metric with CV  = ", sprintf(f, CV2), ": ", sprintf(f, pwr0.2),
"\n    overall power (p1\u00D7p2)    : ", sprintf(f, pwr0.1*pwr0.2),
"\nPower for two simultaneous TOSTs (",
formatC(nsims, digits=0, format="d", big.mark = ","), " simulations each)")
cat(res0, paste0(res1), "\n")

Gives:

CV1: 0.3000, CV2: 0.2000
Sample size based on max(CV1, CV2) = 0.3000: 40
Power for two independent TOSTs

PK metric with CV  = 0.3000: 0.8158
PK metric with CV  = 0.2000: 0.9848
overall power (p1×p2)    : 0.8035
Power for two simultaneous TOSTs (1,000,000 simulations each)
rho = 1.0000: 0.8162
rho = 0.7500: 0.8151
rho = 0.5000: 0.8111
rho = 0.2500: 0.8071

rho = 0.0000: 0.8041

If ρ=1, power ~ the one by TOST of the PK metric with the higher CV. Implicitly people assume a perfect correlation when estimating the sample size based on the PK metric with the higher CV.
If ρ=0, power ~ pTOST1 × pTOST2. 证明完毕 Similar for three tests (e.g., for the FDA). Let’s assume the CV of AUC0–∞ with 0.22 to be a little bit larger than the one of AUC0–t with 0.2. Then we would get pTOST1 × pTOST2 × pTOST3 = 0.8158×0.9848×0.9660 = 0.7762. Since likely the correlation is high (esp. between AUC0–t and AUC0–∞), a relative drop in power from the desired 0.8 by less than 3% doesn’t worry me. In practice (high correlation) the loss will be negligible.

Another example. Since CV1 scratches the limit of HVD(P)s, it might be a good idea to be more cautious and assume a T/R of 0.90 (and – if you are courageous – assume a nicer one of AUC at 0.925). Let’s try a 4-period full replicate design:

library(PowerTOST)
CV1      <- 0.3 # Cmax
CV2      <- 0.2 # AUC
design   <- "2x2x4"
theta0.1 <- 0.90
theta0.2 <- 0.925
n1       <- sampleN.TOST(CV=CV1, theta0=theta0.1, design=design,
print=FALSE)[["Sample size"]]
n2       <- sampleN.TOST(CV=CV2, theta0=theta0.2, design=design,
print=FALSE)[["Sample size"]]
n        <- max(n1, n2)
nsims    <- 1e6
rho.min  <- 0.25
rho.max  <- 0.75
rho.step <- 0.25
rho      <- c(1-.Machine$double.eps, seq(rho.max, rho.min, -rho.step), .Machine$double.eps)
pwr0.1   <- power.TOST(CV=CV1, theta0=theta0.1, n=n, design=design)
pwr0.2   <- power.TOST(CV=CV2, theta0=theta0.2, n=n, design=design)
pwr1     <- numeric(length(rho))
res1     <- character(length(rho))
f        <- "%.4f"
for (j in seq_along(rho)) {
pwr1[j] <- power.2TOST(CV=c(CV1, CV2), theta0=c(theta0.1, theta0.2),
n=n, design=design, rho=rho[j], nsims=nsims)
res1[j] <- paste0("\n  rho = ", sprintf(f, rho[j]), ": ",
sprintf(f, pwr1[j]))
}
res0     <- paste0("\nCV1     : ", sprintf(f, CV1),
", CV2     : ", sprintf(f, CV2),
"\ntheta0.1: ", sprintf(f, theta0.1), ", theta0.2: ", sprintf(f, theta0.2),
"\nSample size based on max(CV1, CV2) = ", sprintf(f, max(CV1, CV2)),
": ", n, " (", design, " design)",
"\nPower for two independent TOSTs",
"\n  PK metric with CV  = ", sprintf(f, CV1), ": ", sprintf(f, pwr0.1),
"\n  PK metric with CV  = ", sprintf(f, CV2), ": ", sprintf(f, pwr0.2),
"\n    overall power (p1\u00D7p2)    : ", sprintf(f, pwr0.1*pwr0.2),
"\nPower for two simultaneous TOSTs (",
formatC(nsims, digits=0, format="d", big.mark = ","), " simulations each)")
cat(res0, paste0(res1), "\n")

Gives:

CV1     : 0.3000, CV2     : 0.2000
theta0.1: 0.9000, theta0.2: 0.9250
Sample size based on max(CV1, CV2) = 0.3000: 40 (2x2x4 design)
Power for two independent TOSTs
PK metric with CV  = 0.3000: 0.8100
PK metric with CV  = 0.2000: 0.9985
overall power (p1×p2)    : 0.8088
Power for two simultaneous TOSTs (1,000,000 simulations each)
rho = 1.0000: 0.8101
rho = 0.7500: 0.8105
rho = 0.5000: 0.8102
rho = 0.2500: 0.8096
rho = 0.0000: 0.8094

If you assume a T/R-ratio of 0.90 for both (probably better):

CV1     : 0.3000, CV2     : 0.2000
theta0.1: 0.9000, theta0.2: 0.9000
Sample size based on max(CV1, CV2) = 0.3000: 40 (2x2x4 design)
Power for two independent TOSTs
PK metric with CV  = 0.3000: 0.8100
PK metric with CV  = 0.2000: 0.9819
overall power (p1×p2)    : 0.7953
Power for two simultaneous TOSTs (1,000,000 simulations each)
rho = 1.0000: 0.8101
rho = 0.7500: 0.8089
rho = 0.5000: 0.8041
rho = 0.2500: 0.7992
rho = 0.0000: 0.7958

Dif-tor heh smusma 🖖
Helmut Schütz The quality of responses received is directly proportional to the quality of the question asked. 🚮
Science Quotes Ing. Helmut Schütz 