Spaghetti viennese [🇷 for BE/BA]

posted by Helmut Homepage – Vienna, Austria, 2015-08-15 05:22 (3542 d 20:45 ago) – Posting: # 15272
Views: 12,285

Hi Mittyri,

hey good idea! I merged our pasta; some cosmetics. Added a “clinical jus­ti­fi­ca­tion” flag (T|F) which forces to ABE for Cmax if FALSE:

###### input section ######
GMR      <- c(0.90, 0.90) # GMR of Cmax, AUC
CV       <- c(0.55, 0.40) # CV of Cmax, AUC
pwr      <- 0.8           # target power
des      <- "2x2x4"       # ABEL: "2x2x4", "2x2x3", "2x3x3"
                          # ABE : "2x2x2" ("2x2")
just     <- TRUE          # widening for Cmax clin. justified (T|F)
                          # TRUE: ABEL | FALSE: ABE
###########################
##### not implemented #####
n.min    <- 12            # minimum sample size according to GL
reg      <- "EMA"         # "EMA"    (ABEL for CV >0.3)
                          # "ANVISA" (ABEL for CV >0.4)
###########################
library(PowerTOST)
f1       <- function(x) power.TOST(CV=CV[2], theta0=x,
                                   n=n, des=des)-pwr
f2       <- function(x) power.scABEL(CV=CV[1], theta0=x,
                                     n=n, des=des, reg=reg)-pwr
f3       <- function(x) power.TOST(CV=CV[1], theta0=x,
                                   n=n, des=des)-pwr
if (des == "2x2") des <- "2x2x2"
designs  <- c("2x2x2", "2x2x4", "2x2x3", "2x3x3")
type     <- c("RT|TR", "RTRT|TRTR", "RTR|TRT", "RRT|RTR|TRR")
trt0     <- c(2, 4, 3, 3) # treatments / subject
fmt      <- paste0("%.", max(nchar(as.character(c(GMR, CV))))-2, "f")
ifelse (CV[1] <= 0.5, LL <- exp(-0.76*CV2se(CV[1])),
  LL <- exp(-0.76*CV2se(0.5)))                    # lower scaled limit
if (CV[1] <= 0.3 | des == "2x2x2" | just == F) LL <- 0.8 # conv. limit
res      <- matrix(nrow=2, ncol=10, byrow=T, dimnames=list(NULL,
              c("Design", "method", "metric", "GMR", "CV",
                "LL", "UL", "n", "power", "GMRlo")))
            # 1st row: method / PK-metric driving the sample size
            # 2nd row: the other one + lowest GMR keeping target power
res[, 1] <- type[match(des, designs)]
if (des == "2x2x2" | just == FALSE) { # 2x2 or ABEL not justified
  tmp.Cmax <- sampleN.TOST(CV=CV[1], theta0=GMR[1],
                targetpower=pwr, des=des, print=F)
} else { # design suitable and ABEL justified
  tmp.Cmax <- sampleN.scABEL(CV=CV[1], theta0=GMR[1],
                targetpower=pwr, des=des, reg=reg,
                details=F, print=F)
}
n.Cmax   <- tmp.Cmax[["Sample size"]]
pwr.Cmax <- tmp.Cmax[["Achieved power"]]
tmp.AUC  <- sampleN.TOST(CV=CV[2], theta0=GMR[2],
              targetpower=pwr, des=des, print=F) # ABE
n.AUC    <- tmp.AUC[["Sample size"]]
pwr.AUC  <- tmp.AUC[["Achieved power"]]
ifelse (n.Cmax >= n.AUC, n <- n.Cmax, n <- n.AUC)
txt      <- NULL
if (n.Cmax >= n.AUC) { # sample size driven by Cmax
  pwr.AUC <- power.TOST(CV=CV[2], theta0=GMR[2], n=n, des=des)
  GMR.AUC.lo <- uniroot(f1, interval=c(0.8, GMR[2]), tol=1e-6)$root
  ifelse (CV[1] <= 0.3 | des == "2x2x2" | just == FALSE,
    res[1, 2] <- "ABE", res[1, 2] <- "ABEL")
  if (des != "2x2x2" & just == FALSE) {
    txt <- paste("Expanding limits for Cmax clinically not justified",
            "(study will be\nevaluated by \u2013 conventional",
            "\u2013 ABE).\n")
  }
  txt <- paste0(txt, "The sample size is ruled by Cmax.\n",
           "Sample size: ", n, " (", res[1, 2], ", power: ",
           sprintf("%.4f", pwr.Cmax), ")\n",
           "Power of AUC (ABE): ", sprintf("%.4f", pwr.AUC), "\n",
           "Lowest GMR of AUC which will give power ", pwr, ": ",
           sprintf("%.4f", GMR.AUC.lo))
  res[1, 3:10] <- c("Cmax", sprintf(fmt, GMR[1]),
                    sprintf(fmt, CV[1]), sprintf("%.4f", LL),
                    sprintf("%.4f", 1/LL), n,
                    sprintf("%.4f", pwr.Cmax), NA)
  res[2, 2:10] <- c("ABE", "AUC", sprintf(fmt, GMR[2]),
                    sprintf(fmt, CV[2]), sprintf("%.4f", 0.8),
                    sprintf("%.4f", 1.25), n,
                    sprintf("%.4f", pwr.AUC),
                    sprintf("%.4f", GMR.AUC.lo))
} else { # sample size driven by AUC
  if (des != "2x2x2" & just == TRUE) { # ABEL if justified
    pwr.Cmax <- power.scABEL(CV=CV[1], theta0=GMR[1], n=n,
      des=des, reg=reg)
    GMR.Cmax.lo <- uniroot(f2, interval=c(LL, GMR[1]), tol=1e-6)$root
  } else {              # ABE
    pwr.AUC <- power.TOST(CV=CV[1], theta0=GMR[1], n=n, des=des)
    GMR.Cmax.lo <- uniroot(f3, interval=c(LL, GMR[1]), tol=1e-6)$root
  }
  txt <- paste0("The sample size is ruled by AUC.\n",
           "Sample size: ", n, " (ABE, power: ",
           sprintf("%.4f", pwr.AUC), ")\n",
           "Power of Cmax")
  ifelse (CV[1] <= 0.3 | des == "2x2x2" | just == FALSE,
    txt <- paste(txt, "(ABE): "),
    txt <- paste(txt, "(ABEL): "))
  txt <- paste0(txt, sprintf("%.4f", pwr.Cmax), "\n",
           "Lowest GMR of Cmax which will give power ", pwr, ": ",
           sprintf("%.4f", GMR.Cmax.lo))
  res[1, 2:10] <- c("ABE", "AUC", sprintf(fmt, GMR[2]),
                    sprintf(fmt, CV[2]), sprintf("%.4f", 0.8),
                    sprintf("%.4f", 1.25), n,
                    sprintf("%.4f", pwr.AUC), NA)
  ifelse (CV[1] <= 0.3, res[2, 2] <- "ABE", res[2, 2] <- "ABEL")
  res[2, 3:10] <- c("Cmax", sprintf(fmt, GMR[1]),
                    sprintf(fmt, CV[1]), sprintf("%.4f", LL),
                    sprintf("%.4f", 1/LL), n,
                    sprintf("%.4f", pwr.Cmax),
                    sprintf("%.4f", GMR.Cmax.lo))
}
txt      <- paste(txt, "\nTotal number of treatments in study:",
              as.numeric(res[1, 8])*trt0[match(des, designs)], "\n")
res      <- data.frame(res)
print(res, row.names=F); cat(txt)


My first example:

    Design method metric  GMR   CV     LL     UL  n  power  GMRlo
 RTRT|TRTR    ABE    AUC 0.90 0.40 0.8000 1.2500 68 0.8072   <NA>
 RTRT|TRTR   ABEL   Cmax 0.90 0.55 0.6984 1.4319 68 0.9700 0.8435
The sample size is ruled by AUC.
Sample size: 68 (ABE, power: 0.8072)
Power of Cmax (ABEL): 0.9700
Lowest GMR of Cmax which will give power 0.8: 0.8435
Total number of treatments in study: 272


My second example:

    Design method metric  GMR   CV     LL     UL  n  power  GMRlo
 RTRT|TRTR   ABEL   Cmax 0.90 0.35 0.7723 1.2948 34 0.8118   <NA>
 RTRT|TRTR    ABE    AUC 0.95 0.25 0.8000 1.2500 34 0.9917 0.8892
The sample size is ruled by Cmax.
Sample size: 34 (ABEL, power: 0.8118)
Power of AUC (ABE): 0.9917
Lowest GMR of AUC which will give power 0.8: 0.8892
Total number of treatments in study: 136


And yours:

 Design method metric  GMR   CV     LL     UL  n  power  GMRlo
  RT|TR    ABE   Cmax 0.95 0.29 0.8000 1.2500 38 0.8202   <NA>
  RT|TR    ABE    AUC 0.94 0.25 0.8000 1.2500 38 0.8756 0.9232
The sample size is ruled by Cmax.
Sample size: 38 (ABE, power: 0.8202)
Power of AUC (ABE): 0.8756
Lowest GMR of AUC which will give power 0.8: 0.9232
Total number of treatments in study: 76


❝ Detlew, what about implementation in PowerTOST both branches?:-D


I would say that’s overkill. In PowerTOST almost everything is vec­tor­ized (i.e., you can assess different CVs for T and R, calculate power for unbalanced sequences, etc.). I wouldn’t do that.

One of the contributing authors of PowerTOST (Ben) is working on power for correlated PK-metrics. I guess that’s next we will see.

❝ PS: Helmut&Detlew, it seems sometimes that you're thinking on R :lol2:


Better than to think in R. :smoke:


To do: Force sample sizes to 12 for low CVs (according to GLs), reg <- "ANVISA" (ABEL if CV >0.4), different CVs for T and R in replicate designs, throw a warning if in a RTR|TRT-design the estimated sample size is <24.

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
23,424 posts in 4,927 threads, 1,667 registered users;
15 visitors (0 registered, 15 guests [including 0 identified bots]).
Forum time: 02:08 CEST (Europe/Vienna)

It is true that many scientists are not philosophically minded
and have hitherto shown much skill and ingenuity
but little wisdom.    Max Born

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