Interlude I (sample sizes, problems & remedies) [RSABE / ABEL]

posted by Helmut Homepage – Vienna, Austria, 2020-08-14 19:37 (35 d 15:09 ago) – Posting: # 21881
Views: 2,002

Dear all,

while I still hope for a reliable source (i.e., published in a peer-reviewed journal) of the partial replicate, an interlude about sample sizes and more.

Of course, I understand that people prefer three periods over four (less blood volume, lower chance of drop­outs). László Tóthfalusi mentioned (IIRC, »Dissolution Testing, Bio­avail­abi­lity & Bio­equivalence Conference«, Budapest 2006) that power depends on the number of administrations and therefore, if \(\small{N}\) is the sample size of a 2×2×2 crossover, for a 4-period replicate one would need \(\small{n=N/2}\) subjects and for 3-period replicates \(\small{n=3N/4}\). However, this is only approximate because the degrees of freedom are different (see below). Currently, this approximation is implemented – sorry, Dave and Yung-jin – in FARTSSIE and the R-package bear.

   CV design  type    df   n  df   power admins appr match dev part.full
 0.20  2x2x2 conv.   N-2  20  18 0.83468     40                         
 0.20  2x2x4  full 3*n-4  10  26 0.84331     40   10   yes             
 0.20  2x2x3  full 2*n-3  14  25 0.81793     42   16    no   +         
 0.20  2x3x3 part. 2*n-3  15  27 0.84401     45   15   yes             +
 0.25  2x2x2 conv.   N-2  28  26 0.80744     56                         
 0.25  2x2x4  full 3*n-4  14  38 0.81399     56   14   yes             
 0.25  2x2x3  full 2*n-3  22  41 0.83198     66   22   yes             
 0.25  2x3x3 part. 2*n-3  21  39 0.81434     63   21   yes             –
 0.30  2x2x2 conv.   N-2  40  38 0.81585     80                         
 0.30  2x2x4  full 3*n-4  20  56 0.82024     80   20   yes             
 0.30  2x2x3  full 2*n-3  30  57 0.82040     90   30   yes             
 0.30  2x3x3 part. 2*n-3  30  57 0.82040     90   30   yes             =
 0.35  2x2x2 conv.   N-2  52  50 0.80747    104                         
 0.35  2x2x4  full 3*n-4  26  74 0.81090    104   26   yes             
 0.35  2x2x3  full 2*n-3  38  73 0.80082    114   40    no   +         
 0.35  2x3x3 part. 2*n-3  39  75 0.81099    117   39   yes             +
 0.40  2x2x2 conv.   N-2  66  64 0.80525    132                         
 0.40  2x2x4  full 3*n-4  34  98 0.81934    136   34   yes             
 0.40  2x2x3  full 2*n-3  50  97 0.81189    150   50   yes             
 0.40  2x3x3 part. 2*n-3  51  99 0.81940    153   51   yes             +
 0.45  2x2x2 conv.   N-2  82  80 0.80691    164                         
 0.45  2x2x4  full 3*n-4  42 122 0.81823    168   42   yes             
 0.45  2x2x3  full 2*n-3  62 121 0.81220    186   62   yes             
 0.45  2x3x3 part. 2*n-3  63 123 0.81826    189   63   yes             +
 0.50  2x2x2 conv.   N-2  98  96 0.80322    196                         
 0.50  2x2x4  full 3*n-4  50 146 0.81281    200   50   yes             
 0.50  2x2x3  full 2*n-3  74 145 0.80768    222   74   yes             
 0.50  2x3x3 part. 2*n-3  75 147 0.81283    225   75   yes             +
 0.55  2x2x2 conv.   N-2 116 114 0.80386    232                         
 0.55  2x2x4  full 3*n-4  58 170 0.80539    232   58   yes             
 0.55  2x2x3  full 2*n-3  86 169 0.80089    258   88    no   +         
 0.55  2x3x3 part. 2*n-3  87 171 0.80541    261   87   yes             +
 0.60  2x2x2 conv.   N-2 134 132 0.80173    268                         
 0.60  2x2x4  full 3*n-4  68 200 0.80879    272   68   yes             
 0.60  2x2x3  full 2*n-3 100 197 0.80111    300  102    no   +         
 0.60  2x3x3 part. 2*n-3 102 201 0.80880    306  102   yes             +

The approximation works well for the 4-period replicate but not so for the 3-period replicates. Hence, I suggest PowerTOST. In most cases the partial replicate requires more subjects than the 3-period full replicate. :-|

In a nutshell:

 Partial replicate (TRR|RTR|RRT) 

  1. Generally slightly larger sample sizes than full replicates. 〰️
    Since same degrees of freedom, the sample size is a multiple of three instead of two.
  2. Estimation of swR / CVwR.
  3. Estimation of swT / CVwT not possible.
  4. The EMA’s “all fixed effects” model for ABE.
  5. Sometimes convergence issues with the FDA’s covariance structure of the mixed effects model for ABE.* Changing from FA0(2) to FA0(1) or CSH generally – not always! – helps. Should be specified in the SAP. Rarely convergence is not achieved with any specification. 🆘
  6. The EMA’s ABEL (CVwR >30%).
  7. The FDA’s RSABE (swR ≥0.294).

 3-period full replicates (TRT|RTR or TRR|RTT) 

  1. Generally slightly smaller sample sizes than partial replicate. 〰️
    Since same degrees of freedom, the sample size is a multiple of two instead of three.
  2. Estimation of swR / CVwR.
  3. Estimation of swT / CVwT.
  4. The EMA’s “all fixed effects” model for ABE.
  5. The FDA’s covariance structure of the mixed effects model for ABE.
  6. The EMA’s ABEL (CVwR >30%).
  7. The FDA’s RSABE (swR ≥0.294).

#1: Not a big deal; if sample sizes are different, the difference is pretty small.
#3: In a pilot study CVwT is not only nice to know but useful. If CVwT < CVwR you get an incentive in planning the pivotal study (scaling depends on CVwR but the BE assessment on the pooled CVw). If CVwT > CVwR you can account for that and increase the sample size accordingly. If the pilot study was performed in the partial replicate design you have to assume that CVwT = CVwR. If CVwT < CVwR you waste money. If CVwT > CVwR your study will be underpowered. For a pivotal study you can approach the WHO for reference-scaling of AUC (cause a 4-period full replicate is recommended in the guidance).
#5: Can be a show stopper in the partial replicate design. There is a slight risk (ABE for the FDA using FA0(2) acc. to the guidance and no convergence) that the PK metric in question cannot be assessed for ABE at all.

 Given all that, I don’t see any justification
for using the partial replicate design. 

If you know one, please let me know.



R-script for the table:

library(PowerTOST)
balance <- function(x, y) {
  return(y * (x %/% y + as.logical(x %% y)))
}
designs <- known.designs()[c(3, 8, 7, 10), 2:3]
type    <- c("conv.", "full", "full", "part.")
eval(parse(text = designs$df[1]))
CV  <- seq(0.2, 0.6, 0.05)
res <- data.frame(CV = rep(CV, each = 4), design = designs[, 1], type = type,
                  df.1 = designs[, 2], n = NA, df.2 = NA, power = NA,
                  admins = NA, appr = "", match = "", dev = "", part.full = "")
for (j in 1:nrow(res)) {
  tmp <- sampleN.TOST(CV = res$CV[j], design = res$design[j],
                      print = FALSE, details = FALSE)
  res$n[j]     <- tmp[["Sample size"]]
  res$power[j] <- signif(tmp[["Achieved power"]], 5)
  n            <- res$n[j]
  nseq         <- as.numeric(substr(res$design[j], 3, 3))
  nper         <- as.numeric(substr(res$design[j], 5, 5))
  if (res$design[j] == "2x2x2") N <- n
  if (!res$design[j] == "2x2x2") {
    if (nper == 4) res$appr[j] <- balance(N/2, nseq)
    if (nper == 3) res$appr[j] <- balance(3*N/4, nseq)
    if (res$appr[j] == res$n[j]) {
      res$match[j] <- "yes"
    } else {
      res$match[j] <- "no"
      ifelse (res$appr[j] < res$n[j], res$dev[j] <- "\u2013", res$dev[j] <- "+")
    }
    if (res$design[j] == "2x2x3") n.3full <- n
    if (res$design[j] == "2x3x3") {
      if (n < n.3full)  res$part.full[j] <- "\u2013"
      if (n == n.3full) res$part.full[j] <- "="
      if (n > n.3full)  res$part.full[j] <- "+"
    }
  }
  res$admins[j] <- nper*n
  df            <- designs$df[which(designs$design == res$design[j])]
  res$df.2[j]   <- eval(parse(text = df))
}
names(res)[c(4, 6)] <- rep("df", 2)
res[which(res[, 4] == "n-2"), 4] <- "N-2"
print(res, row.names = FALSE)


R-script to simulate 1,000 studies; CV 20–60%, T/R-ratio 0.85–0.95, power 80–90%:

library(PowerTOST)
set.seed(1234567)
sims   <- 1000
CV     <- runif(sims, 0.20, 0.60)
theta0 <- runif(sims, 0.85, 0.95)
target <- runif(sims, 0.80, 0.90)
res    <- data.frame(f = rep(NA, sims), p = NA)
for (j in 1:sims) {
  res$f[j] <- sampleN.TOST(CV = CV[j], theta0 = theta0[j], design = "2x2x3",
                           targetpower = target[j], print = FALSE)[["Sample size"]]
  res$p[j] <- sampleN.TOST(CV = CV[j], theta0 = theta0[j], design = "2x3x3",
                           targetpower = target[j], print = FALSE)[["Sample size"]]
}
bp <- boxplot(res, plot = FALSE)
plot(c(0.5, 2.5), range(bp$stats[1, ], bp$stats[5, ]), type = "n", axes = FALSE,
     xlab = "3-period replicate designs", ylab = "sample size",
     main = paste(sims, "studies simulated for ABE"), cex.main = 1.2, font.main = 1)
abline(h = axTicks(2, log = FALSE), col = "lightgrey", lty = 3)
axis(1, at = 1:2, labels = c("full", "partial"), tick = FALSE)
axis(2, las = 1)
bxp(bp, las = 1, outline = FALSE, boxwex = 0.4, add = TRUE, ann = FALSE,
    boxfill = "bisque", medcol = "blue", axes = FALSE, frame.plot = TRUE)
text(rep(1.25, 5), bp$stats[, 1], labels = bp$stats[, 1], pos = 4)
text(rep(2.25, 5), bp$stats[, 2], labels = bp$stats[, 2], pos = 4)


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,068 posts in 4,392 threads, 1,466 registered users;
online 18 (0 registered, 18 guests [including 9 identified bots]).
Forum time: Saturday 10:46 CEST (Europe/Vienna)

The purpose of models is not to fit the data,
but to sharpen the questions.    Samuel Karlin

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