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

posted by Helmut Homepage – Vienna, Austria, 2018-05-24 12:54 (889 d 02:26 ago) – Posting: # 18812
Views: 3,031

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. 证明完毕 :-D

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
[image]

The quality of responses received is directly proportional to the quality of the question asked. 🚮
Science Quotes

Complete thread:

Activity
 Admin contact
21,179 posts in 4,414 threads, 1,477 registered users;
online 9 (0 registered, 9 guests [including 7 identified bots]).
Forum time: Thursday 14:20 CET (Europe/Vienna)

With four parameters I can fit an elephant,
and with five I can make him wiggle his trunk.    John von Neumann

The Bioequivalence and Bioavailability Forum is hosted by
BEBAC Ing. Helmut Schütz
HTML5