Spaghetti viennese [🇷 for BE/BA]

posted by Helmut Homepage – Vienna, Austria, 2015-08-15 05:22 (3469 d 01:27 ago) – Posting: # 15272
Views: 12,098

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,380 posts in 4,914 threads, 1,662 registered users;
27 visitors (0 registered, 27 guests [including 5 identified bots]).
Forum time: 05:50 CET (Europe/Vienna)

Skill is a function of chance.
It’s an intuitive best-use of chance situations.    Philip K. Dick

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