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

posted by Helmut Homepage – Vienna, Austria, 2018-05-24 14:54 (2156 d 15:52 ago) – Posting: # 18812
Views: 4,117

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)
nsims    <- 1e6
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 🖖🏼 Довге життя Україна! [image]
Helmut Schütz
[image]

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

Complete thread:

UA Flag
Activity
 Admin contact
22,987 posts in 4,824 threads, 1,666 registered users;
96 visitors (0 registered, 96 guests [including 5 identified bots]).
Forum time: 06:46 CEST (Europe/Vienna)

The only way to comprehend what mathematicians mean by Infinity
is to contemplate the extent of human stupidity.    Voltaire

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