replicateBE

Comparative BA-calculation for Average Bioequivalence with Expanding Limits (ABEL)

 
library(replicateBE) # attach the library
# Version 1.1.0 built 2021-06-21 with R 4.1.0
# (stable release on CRAN NA).

Introduction

The library provides datasets (internal .rda and in CSV-format in /extdata/) which support users in a black-box performance qualification (PQ) of their software installations.1 Users can analyze data imported from CSV- and Excel-files.

The methods2 given by the European Medicines Agency (EMA) for reference-scaling according to the Guideline on the Investigation of Bioequivalence3 are implemented. Health Canada’s approach4 – requiring a mixed-effects model – is approximated by intra-subject contrasts. Direct widening of the limits for Cmax (as a special case of ABEL) recommended by the GCC5 is supported as well.

Potential influence of outliers on the variability of the reference can be assessed by box plots of studentized and standardized residuals as suggested at a joint EGA/EMA symposium.6

Functions

method.A()

A linear model of log-transformed PK responses and effects
    sequence, subject(sequence), period, treatment
where all effects are fixed (i.e., evaluated by an ANOVA). Estimated via function lm() of library stats.

modA <- lm(log(PK) ~ sequence + subject%in%sequence + period + treatment,
                     data = data)

method.B()

A linear model of log-transformed PK responses and effects
    sequence, subject(sequence), period, treatment
where subject(sequence) is a random effect and all others are fixed.

Three options are provided

  1. Estimated via function lmer() of library lmerTest.
modB <- lmer(log(PK) ~ sequence + period + treatment + (1|subject),
                       data = data)
  1. Estimated via function lme() of library nlme.
modB <- lme(log(PK) ~ sequence +  period + treatment, random = ~1|subject,
                      data = data)
  1. Estimated via function lmer() of library lmerTest.
modB <- lmer(log(PK) ~ sequence + period + treatment + (1|subject),
                       data = data)

ABE()

Average Bioequivalence, where the model is identical to Method A. By default the conventional acceptance range of 80.00 – 125.00% is used. Tighter limits (90.00 – 111.11%) for narrow therapeutic index drugs (EMA and others) or wider limits (75.00 – 133.33% for Cmax according to the guideline of South Africa10) can be specified by the arguments theta1 (lower limit) and/or theta2 (upper limit).

Hypotheses

The hypotheses are \[\small{H_{0}:\theta_0\ni \left\{L,U\right\}\:vs\:H_{1}:L<\theta_0<U}\] where \(\small{\theta_0=\mu_\textrm{T}/\mu_\textrm{R}}\) and the null hypothesis is inequivalence. In Average Bioequivalence (ABE) the limits \(\small{\left\{L,U\right\}}\) are fixed, whereas in ABEL they can be expanded based on the within-subject variability of the reference treatment.

Tested designs

Details about the reference datasets and their designs:

help("data", package = "replicateBE")
?replicateBE::data

Four period (full) replicates

Both the test and the reference treatments are administered at least once.

Two sequences

TRTR | RTRT
TRRT | RTTR
TTRR | RRTT

Four sequences

TRTR | RTRT | TRRT | RTTR
TRRT | RTTR | TTRR | RRTT

Three period (full) replicates

The test treatment is administered at least once to ½ of the subjects and the reference treatment at least once to the respective other ½ of the subjects.

TRT | RTR
TRR | RTT

Two period (full) replicate

The test and reference treatments are administered once to ½ of the subjects (for the estimation of the CI), i.e., the first group of subjects follows a conventional 2×2×2 trial. In the second group the test and reference treatments are administered at least once to ¼ of the subjects, respectively (for the estimation of CVwT and CVwR).

TR | RT | TT | RR

Although supported, Balaam’s design11 is not recommended due to its poor power characteristics.

Three period (partial) replicates

The test treatment is administered once and the reference treatment at least once.

TRR | RTR | RRT
TRR | RTR

The latter is the so-called extra-reference design12 which is not recommended since it is biased in the presence of period effects.

Data structure

Columns must have the headers subject, period, sequence, treatment, PK, and/or logPK.13 Any order of columns is acceptable. Uppercase and mixed case headers will be internally converted to lowercase headers.

Format

Variable Format
subject Integer numbers or any combination of alphanumerics (A-Z, a-z, -, _, #, 0-9)
period Integer numbers
sequence Numbers or literal sequences not listed in the tested designs are not accepted (e.g., ABAB).
treatment The Test treatment must be coded T and the Reference R (both uppercase).
PK Real positive numbers of PK responses.
logPK Real numbers of already loge-transformed PK responses (optional and rarely needed).

Relevant data are used for the estimation of CVwR (and CVwT in full replicate designs) and BE, i.e., the data­sets might be different (see the example below). It is good practice to state that in the Statistical Analysis Plan.

Incomplete data

Estimation of CVw

If a subject drops out from the study in a higher period, data of repeated administrations will still be used for the estimation of CVw, although data of the other treatment might be missing. Examples for the estimation of CVwR (missing values are denoted by ·):

RTRT | RTR·
TRRT | TRR·
RRTT | RRT· or RR··
RRT | RR··

Assessment of BE

If a subject drops out from the study in a higher period, data with at least one administration of the Test and Reference will be used in the assessment of BE. Examples (missing values are denoted by ·):

TRTR | TRT· or | TR··
RTRT | RTR· or | RT··
TRRT | TRR· or | TR··
RTTR | RTT· or | RT··
TTRR | TTR.
TRT | TR·
RTR | RT·
TRR | TR·
RTR | RT·
RTT | RT·

Example of different datasets

16 subjects enrolled in the study. In sequence RTRT one dropout in the 2nd period and one in the 4th period. In sequence TRTR one dropout in the 3rd period and one in the 4th.

1 RTR.  5 RTRT  9 TRTR 13 RTRT
2 RTRT  6 TR·· 10 TRTR 14 TRT·
3 RTRT  7 RTRT 11 RTRT 15 TRTR
4 TRTR  8 R··· 12 TRTR 16 TRTR

We obtain these datasets:

Dataset Purpose included excluded
#1 Estimation of CVwR 13 who received 2 treatments R 6, 8, 14
#2 Assessment of BE 15 who received ≥1 treatment T and ≥1 treatment R 8
#3 Estimation of CVwT 13 who received 2 treatments T 1, 6, 8

Datasets #1 and #2 are required for ABEL and all three for the WHO’s reference-scaling of AUC (see below). For ABE only dataset #2 is required.

Notes on the methods

Estimation of intra-subject variability

The EMA proposed a linear model of log-transformed PK responses of the reference treatment
    sequence, subject(sequence), period
where all effects are fixed. Estimated via function lm() of library stats:

modCV <- lm(log(PK) ~ sequence + subject%in%sequence + period,
                      data = data[data$treatment = "R", ])

In full replicate designs (required by the WHO for reference-scaling of AUC; see below) the same model is run with data = data[data$treatment = "T", ].

Special conditions for the sample size in three period full replicate designs:

The question raised asks if it is possible to use a design where subjects are randomised to receive treatments in the order of TRT or RTR.

The CHMP bioequivalence guideline requires that at least 12 patients are needed to provide data for a bioequivalence study to be considered valid, and to estimate all the key parameters. Therefore, if a 3-period replicate design, where treatments are given in the order TRT or RTR, is to be used to justify widening of a confidence interval for Cmax then it is considered that at least 12 patients would need to provide data from the RTR arm. This implies a study with at least 24 patients in total would be required if equal number of subjects are allocated to the 2 treatment sequences.

Q&A document14

If less than twelve subjects are eligible in sequence RTR of a TRT | RTR design (and in analogy in sequence TRR of a TRR | RTT design), the user is notified about the ‘uncertain’ estimate of CVwR. However, in a sufficiently powered study such a case is extremely unlikely.
Let us explore the 95% confidence interval of the CV:

# Estimate sample sizes of full replicate designs (theta0 0.90,
# target power 0.80) and CI of the CV with library PowerTOST
CV     <- 0.30
design <- c("2x2x4", "2x2x3") # 4- and 3-period full replicate designs
res    <- data.frame(design = rep(design, 2), n = c(rep(NA, 2), rep(12, 2)),
                     df = NA, CV = CV, lower = NA, upper = NA)
# 95% confidence interval of the CV
for (i in 1:nrow(res)) {
  if (is.na(res$n[i])) {
    res$n[i] <- PowerTOST::sampleN.scABEL(CV = CV,
                                          design = res$design[i],
                                          details = FALSE,
                                          print = FALSE)[["Sample size"]]
  }
  if (i > 2 ) {
    n.1 <- res$n[i-2] / 2 # no dropouts in one sequence
    n.2 <- 12             # only 12 eligible subjects in the other
    res$n[i] <- n.1 + n.2
  }
  if (res$design[i] == "2x2x4") {
    res$df[i] <- 3 * res$n[i] - 4
  } else {
    res$df[i] <- 2 * res$n[i] - 3
  }
  res[i, 5:6] <- round(PowerTOST::CVCL(CV = CV,
                                       df = res$df[i],
                                       side = "2-sided",
                                       alpha = 0.05), 3)
}
print(res, row.names = FALSE)
#  design  n df  CV lower upper
#   2x2x4 34 98 0.3 0.262 0.351
#   2x2x3 50 97 0.3 0.262 0.352
#   2x2x4 29 83 0.3 0.259 0.357
#   2x2x3 37 71 0.3 0.256 0.362
# Rows 1-2: Sample sizes for target power
# Rows 3-4: Only 12 eligible subjects in one sequence

It is incomprehensible why a four period full replicate design is considered by the EMA to give a more ‘reliable’ estimate of the CV than a three period full replicate design.

Model structure

The EMA’s models assume equal [sic] intra-subject variances of Test and Reference (like in 2×2×2 trials) – even if proven false in one of the full replicate designs (were both CVwT and CVwR can be estimated). Hence, among biostatisticians they are called ‘crippled models’ because the replicative nature of the study is ignored.

It should be noted that by default ANOVA() produces a ‘Type I’ table, i.e., all tests are performed against the residual error. Starting with version 1.1.0 ‘Type III’ is employed in order to obtain the correct test for carryover, where subject has to be tested against subject(sequence).15

method.A(data = rds01, print = FALSE, verbose=TRUE)
# 
# Data set DS01: Method A by lm() 
# ----------------------------------- 
# Type III Analysis of Variance Table
# 
# Response: log(PK)
#                   Df   Sum Sq  Mean Sq  F value     Pr(>F)
# sequence           1   0.0077 0.007652  0.00268  0.9588496
# period             3   0.6984 0.232784  1.45494  0.2278285
# treatment          1   1.7681 1.768098 11.05095  0.0010405
# sequence:subject  75 214.1296 2.855061 17.84467 < 2.22e-16
# Residuals        217  34.7190 0.159995                    
# 
# treatment T – R:
#   Estimate Std. Error    t value   Pr(>|t|) 
# 0.14547400 0.04650870 3.12788000 0.00200215 
# 217 Degrees of Freedom

In ‘Type I’ the F value of sequence would be \(\small{\frac{0.007652}{0.159995}=0.04783}\) with \(\small{p(F_{q=0.04783,\,df_1=1,\,df_2=217})\sim 0.827}\), whereas in ‘Type III’ it is \(\small{\frac{0.007652}{2.855061}=0.00268}\) with \(\small{p(F_{q=0.00268,\,df_1=1,\,df_2=75})\sim 0.959}\).

The nested structure subject(sequence) of the methods leads to an over-specified model.16 The simple model
    sequence, subject, period, treatment
gives identical estimates of the residual variance and the treatment effect and hence, its confidence interval.

The same holds true for the EMA’s model to estimate CVwR. The simple model
    subject, period
gives an identical estimate of the residual variance.

Reference-scaling is acceptable for Cmax (immediate release products: BE Guideline) and Cmax, Cmax,ss, Cτ,ss, partialAUC (modified release products17). The intention to expand the limits has to be stated in the protocol and – contrary to the FDA’s RSABE – a clinical justification provided.

Those HVDP for which a wider difference in Cmax is considered clinically irrelevant based on a sound clinical justification can be assessed with a widened acceptance range. The request for widened interval must be prospectively specified in the protocol.

BE Guideline

BE limits, PE restriction, rounding issues

The limits can be expanded based on CVwR.

The special case recommended by the GCC is:

In reference-scaling a so-called mixed (a.k.a. aggregate) criterion is applied. In order to pass ABEL,

To avoid discontinuities due to double rounding, expanded limits are calculated in full numeric precision and only the confidence interval is rounded according to the guideline.

# Calculate limits with library PowerTOST
CV <- c(30, 50, 57.382)
df <- data.frame(CV = CV,
                 reg1 = "EMA", L1 = NA, U1 = NA, cap1 = "",
                 reg2 = "HC",  L2 = NA, U2 = NA, cap2 = "",
                 reg3 = "GCC", L3 = NA, U3 = NA, cap3 = "",
                 stringsAsFactors = FALSE)
for (i in seq_along(CV)) {
  df[i, 3:4]   <- sprintf("%.3f",
                          PowerTOST::scABEL(CV[i]/100,
                                            regulator = df$reg1[i])*100)
  df[i, 7:8]   <- sprintf("%.1f",
                          PowerTOST::scABEL(CV[i]/100,
                                            regulator = df$reg2[i])*100)
  df[i, 11:12] <- sprintf("%.3f",
                          PowerTOST::scABEL(CV[i]/100,
                                            regulator = df$reg3[i])*100)
}
df$cap3[df$CV <= 30] <- df$cap2[df$CV <= 30] <- df$cap1[df$CV <= 30] <- "lower"
df$cap1[df$CV >= 50 & df$reg1 == "EMA"]    <- "upper"
df$cap2[df$CV >= 57.382 & df$reg2 == "HC"] <- "upper"
names(df) <- c("CV(%)", rep(c("reg", "L(%)", "U(%)", "cap"), 3))
print(df, row.names = FALSE)
#   CV(%) reg   L(%)    U(%)   cap reg L(%)  U(%)   cap reg   L(%)    U(%)   cap
#  30.000 EMA 80.000 125.000 lower  HC 80.0 125.0 lower GCC 80.000 125.000 lower
#  50.000 EMA 69.837 143.191 upper  HC 69.8 143.2       GCC 75.000 133.333      
#  57.382 EMA 69.837 143.191 upper  HC 66.7 150.0 upper GCC 75.000 133.333

Discrete limits resulting from rounding (EMA)

Degrees of freedom, comparison of methods

The SAS code provided by the EMA in the Q&A document does not specify how the degrees of freedom should be calculated in Method B. Hence, the default in PROC MIXED, namely DDFM=CONTAIN is applied, i.e., method.B(..., option = 2). For incomplete data (missing periods) Satterthwaite’s approximation of the degrees of freedom, i.e., method.B(..., option = 1) or Kenward-Roger method.B(..., option = 3) might be a better choice – if stated as such in the SAP.
For background about approximations in different software packages see the electronic Supplementary Material of Schütz et al.

The EMA seemingly prefers Method A:

A simple linear mixed model, which assumes identical within-subject variability (Method B), may be acceptable as long as results obtained with the two methods do not lead to different regulatory decisions. However, in borderline cases […] additional analysis using Method A might be required.

Q&A document (January 2011 and later revisions)

The half-width of the confidence interval in log-scale allows a comparison of methods (B v.s. A) where a higher value might point towards a more conservative decision.18 In the provided example datasets – with one exception – the conclusion of BE (based on the mixed criterion) agrees between Method A and Method B.
However, for the highly incomplete dataset 14 Method A was liberal (passing by ANOVA but failing by the random effects model):

# Compare Method B acc. to the GL with Method A for all reference data sets.
ds <- substr(grep("rds", unname(unlist(data(package = "replicateBE"))),
                  value = TRUE), start = 1, stop = 5)
for (i in seq_along(ds)) {
  A <- method.A(print = FALSE, details = TRUE, data = eval(parse(text = ds[i])))$BE
  B <- method.B(print = FALSE, details = TRUE, data = eval(parse(text = ds[i])))$BE
  r <- paste0("A ", A, ", B ", B, " \u2013 ")
  cat(paste0(ds[i], ":"), r)
  if (A == B) {
    cat("Methods agree.\n")
  } else {
    if (A == "fail" & B == "pass") {
      cat("Method A is conservative.\n")
    } else {
      cat("Method B is conservative.\n")
    }
  }
}
# rds01: A pass, B pass – Methods agree.
# rds02: A pass, B pass – Methods agree.
# rds03: A pass, B pass – Methods agree.
# rds04: A fail, B fail – Methods agree.
# rds05: A pass, B pass – Methods agree.
# rds06: A pass, B pass – Methods agree.
# rds07: A pass, B pass – Methods agree.
# rds08: A pass, B pass – Methods agree.
# rds09: A pass, B pass – Methods agree.
# rds10: A pass, B pass – Methods agree.
# rds11: A pass, B pass – Methods agree.
# rds12: A fail, B fail – Methods agree.
# rds13: A fail, B fail – Methods agree.
# rds14: A pass, B fail – Method B is conservative.
# rds15: A fail, B fail – Methods agree.
# rds16: A fail, B fail – Methods agree.
# rds17: A fail, B fail – Methods agree.
# rds18: A fail, B fail – Methods agree.
# rds19: A fail, B fail – Methods agree.
# rds20: A fail, B fail – Methods agree.
# rds21: A fail, B fail – Methods agree.
# rds22: A pass, B pass – Methods agree.
# rds23: A pass, B pass – Methods agree.
# rds24: A pass, B pass – Methods agree.
# rds25: A pass, B pass – Methods agree.
# rds26: A fail, B fail – Methods agree.
# rds27: A pass, B pass – Methods agree.
# rds28: A pass, B pass – Methods agree.
# rds29: A pass, B pass – Methods agree.
# rds30: A fail, B fail – Methods agree.

Exploring dataset 14:

A  <- method.A(print = FALSE, details = TRUE, data = rds14)
B1 <- method.B(print = FALSE, details = TRUE, data = rds14, option = 1)
B2 <- method.B(print = FALSE, details = TRUE, data = rds14) # apply default option
B3 <- method.B(print = FALSE, details = TRUE, data = rds14, option = 3)
# Rounding of CI according to the GL
A[17:21]  <- round(A[17:21],  2) # all effects fixed
B1[17:21] <- round(B1[17:21], 2) # Satterthwaite's df
B2[17:21] <- round(B2[17:21], 2) # df acc. to Q&A
B3[17:21] <- round(B3[17:21], 2) # Kenward-Roger df
cs <- c(2, 10, 17:25)
df <- rbind(A[cs], B1[cs], B2[cs], B3[cs])
names(df)[c(1, 3:6, 11)] <- c("Meth.", "L(%)", "U(%)",
                              "CL.lo(%)", "CL.hi(%)", "hw")
df[, c(2, 11)] <- signif(df[, c(2, 11)], 5)
print(df[order(df$BE, df$hw, decreasing = c(FALSE, TRUE)), ],
      row.names = FALSE)
#  Meth.     DF  L(%)   U(%) CL.lo(%) CL.hi(%) PE(%)   CI  GMR   BE      hw
#      A 197.44 69.84 143.19    69.21   121.27 91.62 fail pass fail 0.28043
#      A 192.00 69.84 143.19    69.21   121.28 91.62 fail pass fail 0.28046
#      A 195.99 69.84 143.19    69.21   121.28 91.62 fail pass fail 0.28052
#      A 192.00 69.84 143.19    69.99   123.17 92.85 pass pass pass 0.28261

All variants of Method B are more conservative than Method A. Before rounding the confidence interval, option = 2 with 192 degrees of freedom would be more conservative (lower CL 69.21029) than option = 1 with 197.44 degrees of freedom (lower CL 69.21286). Given the incompleteness of this data set (four missings in period 2, twelve in period 3, and 19 in period 4), Satterthwaite’s or Kenward-Roger degrees of freedom are probably the better choice.

For detailed comparisons between methods based on simulations see the electronic Supplementary Material of Schütz et al.

Outlier analysis

It is an open issue how outliers should be handled.

The applicant should justify that the calculated intra-subject variability is a reliable estimate and that it is not the result of outliers.

BE Guideline

The author ‘suggested’ box plots as a mere joke [sic] at the EGA/EMA symposium, being aware of their non­para­metric nature and the EMA’s reluctance towards robust methods. Alas, this joke was included in the Q&A document.

[…] a study could be acceptable if the bioequivalence requirements are met both including the outlier subject (using the scaled average bioequivalence approach and the within-subject CV with this subject) and after exclusion of the outlier (using the within-subject CV without this subject).

An outlier test is not an expectation of the medicines agencies but outliers could be shown by a box plot. This would allow the medicines agencies to compare the data between them.

EGA/EMA Q&A document

With the additional argument ola = TRUE in method.A() and method.B() an outlier analysis is performed, where the default fence = 2.19

Results differ slightly depending on software’s algorithms to calculate the median and quartiles. Example with the ‘types’ implemented in R (note the differences even in the medians):

### Compare different types with some random data
x <- rnorm(48)
p <- c(25, 50, 75)/100
q <- matrix(data = "", nrow = 9, ncol = 4,
            dimnames = list(paste("type =", 1:9),
                            c("1st quart.", "median", "3rd quart.",
                              "software / default")))
for (i in 1:9) {
  q[i, 1:3] <- sprintf("%.5f", quantile(x, prob = p, type = i))
}
q[c(2, 4, 6:8), 4] <- c("SAS, Stata", "SciPy", "Phoenix, Minitab, SPSS",
                        "R, S, MATLAB, Octave, Excel", "Maple")
print(as.data.frame(q))
#          1st quart.   median 3rd quart.          software / default
# type = 1   -0.86817 -0.40487    0.29546                            
# type = 2   -0.85617 -0.38854    0.30042                  SAS, Stata
# type = 3   -0.86817 -0.40487    0.29546                            
# type = 4   -0.86817 -0.40487    0.29546                       SciPy
# type = 5   -0.85617 -0.38854    0.30042                            
# type = 6   -0.86217 -0.38854    0.30290      Phoenix, Minitab, SPSS
# type = 7   -0.85017 -0.38854    0.29794 R, S, MATLAB, Octave, Excel
# type = 8   -0.85817 -0.38854    0.30124                       Maple
# type = 9   -0.85767 -0.38854    0.30104

Example for the reference dataset 01:

Outlier analysis
 (externally) studentized residuals
 Limits (2×IQR whiskers): -1.717435, 1.877877
 Outliers:
 subject sequence  stud.res
      45     RTRT -6.656940
      52     RTRT  3.453122

 standarized (internally studentized) residuals
 Limits (2×IQR whiskers): -1.69433, 1.845333
 Outliers:
 subject sequence stand.res
      45     RTRT -5.246293
      52     RTRT  3.214663

If based on studentized residuals outliers are detected, additionally to the expanded limits based on the complete reference data, tighter limits are calculated based on CVwR after exclusion of outliers and BE assessed with the new limits. Note that standardized residuals are given for informational purposes only and not used for exclusion of outliers.

Output for the reference dataset 01 (re-ordered for clarity):

CVwR               :  46.96% (reference-scaling applicable)
swR                :   0.44645
Expanded limits    :  71.23% ... 140.40% [100exp(±0.760·swR)]
Assessment based on original CVwR 46.96%
────────────────────────────────────────
Confidence interval: 107.11% ... 124.89%  pass
Point estimate     : 115.66%              pass
Mixed (CI & PE)    :                      pass
 ╟────────┼─────────────────────┼───────■────────◊─────────■───────────────╢

Outlier fence      :  2×IQR of studentized residuals.
Recalculation due to presence of 2 outliers (subj. 45|52)
─────────────────────────────────────────────────────────
CVwR (outl. excl.) :  32.16% (reference-scaling applicable)
swR (recalculated) :   0.31374
Expanded limits    :  78.79% ... 126.93% [100exp(±0.760·swR)]
Assessment based on recalculated CVwR 32.16%
────────────────────────────────────────────
Confidence interval: pass
Point estimate     : pass
Mixed (CI & PE)    : pass
         ╟┼─────────────────────┼───────■────────◊─────────■─╢

Note that the PE and its CI are not affected since the entire data are used and therefore, these values not reported in the second analysis (only the conclusion of the assessment).
The ‘line plot’ is given for informational purposes since its resolution is only ~0.5%. The filled squares are the lower and upper 90% confidence limits, the rhombus the point estimate, the vertical lines at 100% and the PE restriction (80.00 – 125.00%), and the double vertical lines the expanded limits. The PE and CI take pre­se­dence over other symbols. In this case the upper limit of the PE restriction is not visible.
Since both analyses arrive at the same conclusion, the study should be acceptable according to the Q&A document.

Applicability, caveats, outlook

The EMA’s approach of reference-scaling for highly variable drugs / drug products is currently recommended in other jurisdictions as well (e.g., the WHO; the ASEAN, Australia, Brazil, Chile, the East African Community, Egypt, the EEU, New Zealand, and the Russian Federation). Health Canada accepts ABEL only for AUC with an upper cap of scaling at ~57.4% (maximum expansion to 66.7 – 150.0%) and might require a true mixed-effects model. Whether Method B is acceptable is unclear.

If degrees of freedom are approximated (Satterthwaite, Kenward-Roger), the SAP and statistical report should always specify which method will be / was used (see above) in order to allow recalculation in other software. This package uses the expected information matrix.23

The estimated CVwR is always uncertain (the degree of uncertainty depends on the CVwR itself, the design, and – to a minor degree – the sample size), which might lead to an inflation of the type I error (i.e., if ABEL is falsely applied although the true – but unknown – CVwR is lower than its estimate).24, 25
Use the optional argument method.A(..., adjust = TRUE) to iteratively adjust α to control the type I error.26
If you want to apply the most conservative approach of Molins et al.27 (which corrects for CVwR 30% instead of the observed one), get the data.frame of results with
  x <- method.A(..., details = TRUE, print = FALSE).
Adjust α in library PowerTOST and call method.A() again:
  design <- "2x2x4" # your design
  n <- as.integer(strsplit(x[[6]], "|", fixed = TRUE)[[1]]) # subjects / sequence
  y <- PowerTOST::scABEL.ad(CV = 0.3, n = n, design = design, print = FALSE)
  method.A(..., alpha = y$alpha.adj)

The WHO accepts reference-scaling for AUC (four period full replicate studies are mandatory in order to assess the vari­ability associated with each product).28 It is not evident how this assessment should be done.
In PBE and IBE the swT/swR ratio was assessed and ‘similar’ variability concluded for a ratio within 0.667 – 1.500. However, the power of comparing variabilities in a study designed to compare means is low. This was one of the reasons why PBE and IBE were not implemented in regulatory practice. An alternative approach is given by the FDA where variabilities are considered ‘comparable’ if the upper confidence limit of σwT/σwR is ≤2.5.29

Cross-validation

Results of all reference datasets agree with ones obtained in SAS (9.4), Phoenix WinNonlin (6.4–8.1), STATISTICA (13), SPSS (22.0), Stata (15.0), and JMP (10.0.2).

Contributors

License

GPL-3 Helmut Schütz 2021-06-21

Disclaimer

Program offered for Use without any Guarantees and Absolutely No Warranty. No Liability is accepted for any Loss and Risk to Public Health Resulting from Use of this R-Code.

Session Information

Inspect this information for reproducibility. Of particular importance are the versions of R and the packages used to create this workflow. It is considered good practice to record this information with every analysis.

options(width = 59)
devtools::session_info()
# - Session info ------------------------------------------
#  setting  value                       
#  version  R version 4.1.0 (2021-05-18)
#  os       Windows 7 x64 SP 1          
#  system   x86_64, mingw32             
#  ui       RTerm                       
#  language EN                          
#  collate  C                           
#  ctype    German_Germany.1252         
#  tz       Europe/Vienna               
#  date     2021-06-21                  
# 
# - Packages ----------------------------------------------
#  package       * version    date       lib source        
#  backports       1.2.1      2020-12-09 [2] CRAN (R 4.1.0)
#  boot            1.3-28     2021-05-03 [2] CRAN (R 4.1.0)
#  broom           0.7.7      2021-06-13 [2] CRAN (R 4.1.0)
#  bslib           0.2.5.1    2021-05-18 [2] CRAN (R 4.1.0)
#  cachem          1.0.5      2021-05-15 [2] CRAN (R 4.1.0)
#  callr           3.7.0      2021-04-20 [2] CRAN (R 4.1.0)
#  cellranger      1.1.0      2016-07-27 [2] CRAN (R 4.1.0)
#  cli             2.5.0      2021-04-26 [2] CRAN (R 4.1.0)
#  colorspace      2.0-1      2021-05-04 [2] CRAN (R 4.1.0)
#  crayon          1.4.1      2021-02-08 [2] CRAN (R 4.1.0)
#  cubature        2.0.4.2    2021-05-13 [2] CRAN (R 4.1.0)
#  desc            1.3.0      2021-03-05 [2] CRAN (R 4.1.0)
#  devtools        2.4.2      2021-06-07 [2] CRAN (R 4.1.0)
#  digest          0.6.27     2020-10-24 [2] CRAN (R 4.1.0)
#  dplyr           1.0.7      2021-06-18 [2] CRAN (R 4.1.0)
#  ellipsis        0.3.2      2021-04-29 [2] CRAN (R 4.1.0)
#  evaluate        0.14       2019-05-28 [2] CRAN (R 4.1.0)
#  fansi           0.5.0      2021-05-25 [2] CRAN (R 4.1.0)
#  fastmap         1.1.0      2021-01-25 [2] CRAN (R 4.1.0)
#  fs              1.5.0      2020-07-31 [2] CRAN (R 4.1.0)
#  generics        0.1.0      2020-10-31 [2] CRAN (R 4.1.0)
#  ggplot2         3.3.4      2021-06-16 [2] CRAN (R 4.1.0)
#  glue            1.4.2      2020-08-27 [2] CRAN (R 4.1.0)
#  gtable          0.3.0      2019-03-25 [2] CRAN (R 4.1.0)
#  htmltools       0.5.1.1    2021-01-22 [2] CRAN (R 4.1.0)
#  jquerylib       0.1.4      2021-04-26 [2] CRAN (R 4.1.0)
#  jsonlite        1.7.2      2020-12-09 [2] CRAN (R 4.1.0)
#  knitr           1.33       2021-04-24 [2] CRAN (R 4.1.0)
#  lattice         0.20-44    2021-05-02 [2] CRAN (R 4.1.0)
#  lifecycle       1.0.0      2021-02-15 [2] CRAN (R 4.1.0)
#  lme4            1.1-27     2021-05-15 [2] CRAN (R 4.1.0)
#  lmerTest        3.1-3      2020-10-23 [2] CRAN (R 4.1.0)
#  magrittr        2.0.1      2020-11-17 [2] CRAN (R 4.1.0)
#  MASS            7.3-54     2021-05-03 [2] CRAN (R 4.1.0)
#  Matrix          1.3-4      2021-06-01 [2] CRAN (R 4.1.0)
#  memoise         2.0.0      2021-01-26 [2] CRAN (R 4.1.0)
#  minqa           1.2.4      2014-10-09 [2] CRAN (R 4.1.0)
#  munsell         0.5.0      2018-06-12 [2] CRAN (R 4.1.0)
#  mvtnorm         1.1-2      2021-06-07 [2] CRAN (R 4.1.0)
#  nlme            3.1-152    2021-02-04 [2] CRAN (R 4.1.0)
#  nloptr          1.2.2.2    2020-07-02 [2] CRAN (R 4.1.0)
#  numDeriv        2016.8-1.1 2019-06-06 [2] CRAN (R 4.1.0)
#  pbkrtest        0.5.1      2021-03-09 [2] CRAN (R 4.1.0)
#  pillar          1.6.1      2021-05-16 [2] CRAN (R 4.1.0)
#  pkgbuild        1.2.0      2020-12-15 [2] CRAN (R 4.1.0)
#  pkgconfig       2.0.3      2019-09-22 [2] CRAN (R 4.1.0)
#  pkgload         1.2.1      2021-04-06 [2] CRAN (R 4.1.0)
#  PowerTOST       1.5.3.9000 2021-05-26 [2] local         
#  prettyunits     1.1.1      2020-01-24 [2] CRAN (R 4.1.0)
#  processx        3.5.2      2021-04-30 [2] CRAN (R 4.1.0)
#  ps              1.6.0      2021-02-28 [2] CRAN (R 4.1.0)
#  purrr           0.3.4      2020-04-17 [2] CRAN (R 4.1.0)
#  R6              2.5.0      2020-10-28 [2] CRAN (R 4.1.0)
#  Rcpp            1.0.6      2021-01-15 [2] CRAN (R 4.1.0)
#  readxl          1.3.1      2019-03-13 [2] CRAN (R 4.1.0)
#  remotes         2.4.0      2021-06-02 [2] CRAN (R 4.1.0)
#  replicateBE   * 1.1.0      2021-06-21 [1] local         
#  rlang           0.4.11     2021-04-30 [2] CRAN (R 4.1.0)
#  rmarkdown       2.9        2021-06-15 [2] CRAN (R 4.1.0)
#  rprojroot       2.0.2      2020-11-15 [2] CRAN (R 4.1.0)
#  sass            0.4.0      2021-05-12 [2] CRAN (R 4.1.0)
#  scales          1.1.1      2020-05-11 [2] CRAN (R 4.1.0)
#  sessioninfo     1.1.1      2018-11-05 [2] CRAN (R 4.1.0)
#  stringi         1.6.1      2021-05-10 [2] CRAN (R 4.1.0)
#  stringr         1.4.0      2019-02-10 [2] CRAN (R 4.1.0)
#  TeachingDemos   2.12       2020-04-07 [2] CRAN (R 4.1.0)
#  testthat        3.0.3      2021-06-16 [2] CRAN (R 4.1.0)
#  tibble          3.1.2      2021-05-16 [2] CRAN (R 4.1.0)
#  tidyr           1.1.3      2021-03-03 [2] CRAN (R 4.1.0)
#  tidyselect      1.1.1      2021-04-30 [2] CRAN (R 4.1.0)
#  usethis         2.0.1      2021-02-10 [2] CRAN (R 4.1.0)
#  utf8            1.2.1      2021-03-12 [2] CRAN (R 4.1.0)
#  vctrs           0.3.8      2021-04-29 [2] CRAN (R 4.1.0)
#  withr           2.4.2      2021-04-18 [2] CRAN (R 4.1.0)
#  xfun            0.24       2021-06-15 [2] CRAN (R 4.1.0)
#  yaml            2.2.1      2020-02-01 [2] CRAN (R 4.1.0)
# 
# [1] C:/Users/HS/AppData/Local/Temp/RtmpwvPwNV/Rinst14b045d27892
# [2] D:/Program Files/R/R-4.1.0/library

  1. Schütz H, Tomashevskiy M, Labes D, Shitova A, González-de la Parra M, Fuglsang A. Reference Data­sets for Studies in a Replicate Design Intended for Average Bioequivalence with Expanding Limits. AAPS J. 2020; 22(2): Article 44. doi:10.1208/s12248-020-0427-6.↩︎

  2. European Medicines Agency. EMA/582648/2016 Annex I. London. 21 September 2016.↩︎

  3. European Medicines Agency. Committee for Medicinal Products for Human Use. Guideline on the Investigation of Bioequivalence. CPMP/EWP/QWP/1401/98 Rev. 1/Corr **. London. 20 January 2010.↩︎

  4. Health Canada. Guidance Document. Conduct and Analysis of Comparative Bioavailability Studies. Ottawa. 2018/06/08.↩︎

  5. Executive Board of the Health Ministers’ Council for GCC States. The GCC Guidelines for Bioequivalence. March 2016.↩︎

  6. European Generic Medicines Association. Revised EMA Bioequivalence Guideline. Questions & Answers. 3rd EGA Symposium on Bioequivalence. London. 1 June 2010.↩︎

  7. Satterthwaite FE. An Approximate Distribution of Estimates of Variance Components. Biometr Bull. 1946; 2(6): 110–4. doi:10.2307/3002019.↩︎

  8. Kenward MG, Roger JH. Small Sample Inference for Fixed Effects from Restricted Maximum Likelihood. Biometrics. 1997; 53(3): 983–97. doi:10.2307/2533558.↩︎

  9. Kackar RN, Harville DA. Approximations for Standard Errors of Estimators of Fixed and Random Effects in Mixed Linear Models. J Am Stat Assoc. 1984; 79(388): 853–62. doi:10.1080/01621459.1984.10477102.↩︎

  10. Medicines Control Council. Registration of Medicines. Biostudies. Pretoria. June 2015.↩︎

  11. Balaam LN. A Two-Period Design with t2 Experimental Units. Biometrics. 1968; 24(1): 61–73. doi:10.2307/2528460.↩︎

  12. Chow, SC, Shao J, Wang H. Individual bioequivalence testing under 2×3 designs. Stat Med. 2002; 21(5): 629–48. doi:10.1002/sim.1056.↩︎

  13. Napierian logarithm (base e). The decadic logarithm (base 10) is not supported).↩︎

  14. European Medicines Agency. Questions & Answers: positions on specific questions addressed to the Pharmacokinetics Working Party (PKWP). EMA/618604/2008. London, June 2015 (and later revisons).↩︎

  15. Chow S-C, Liu J-p. Design and Analysis of Bioavailability and Bioequivalence Studies. Boca Raton: CRC Press; 3rd ed. 2009. Chapter 3.2.↩︎

  16. It contradicts the law of parsimony. Such a nesting is superfluous since in comparative bioavailability trials subjects are uniquely coded. If, say, subject 1 is allocated to sequence TRTR there is not yet ‘another’ subject 1 allocated to sequence RTRT. This explains the many lines in SAS PROC GML given with . and in Phoenix WinNonlin as not estimable.↩︎

  17. European Medicines Agency, Committee for Medicinal Products for Human Use. Guideline on the pharmacokinetic and clinical evaluation of modified release dosage forms. EMA/CHMP/EWP/280/96. London, 20 November 2014.↩︎

  18. Of course, only if point estimates are identical.↩︎

  19. The fences are given by the lowest datum still within m×IQR of the lower quartile, and the highest datum still within m×IQR of the upper quartile, where IQR is the interquartile range (difference between the 3rd and 1st quartiles). Data outside fences are considered outliers. Decreasing the multiplier m to e.g., 1.5 might result in many outliers, whereas increasing the multiplier in only a few.
    Different methods exist to calculate quartiles (nine ‘types’ are available in R, where the default is type = 7). R’s default is used by S, MATLAB, Octave, and Excel. Phoenix WinNonlin, Minitab, and SPSS use type = 6, ScyPy uses type = 4, whereas the default in SAS and Stata is type = 2 (though others are available as well).↩︎

  20. Externally studentized: \(\small{\widehat{\sigma}_{(i)}^2={1 \over n-m-1}\sum_{\begin{smallmatrix}j = 1\\j \ne i\end{smallmatrix}}^n \widehat{\varepsilon\,}_j^{\,2}}\)↩︎

  21. Internally studentized: \(\small{\widehat{\sigma}^2={1 \over n-m}\sum_{j=1}^n \widehat{\varepsilon\,}_j^{\,2}}\)↩︎

  22. Both are available in SAS and R, whereas only the latter in e.g., Phoenix WinNonlin. In general the former are slightly more restrictive. Which one will be used has to be stated in the SAP.↩︎

  23. For Satterthwaite only available in Phoenix WinNonlin, SPSS, and Stata; as an option in SAS by SCORING=1. For Kenward-Roger default option EIM in Stata. The observed information matrix is the only available in JMP and default SCORING=0 in SAS; option OIM in Stata.↩︎

  24. Wonnemann M, Frömke C, Koch A. Inflation of the Type I Error: Investigations on Regulatory Recommendations for Bioequivalence of Highly Variable Drugs. Pharm Res. 2015; 32(1): 135–43. doi:10.1007/s11095-014-1450-z.↩︎

  25. Muñoz J, Alcaide D, Ocaña J. Consumer’s risk in the EMA and FDA regulatory approaches for bioequivalence in highly variable drugs. Stat Med. 2016; 35(12): 1933–43. doi:10.1002/sim.6834.↩︎

  26. Labes D, Schütz H. Inflation of Type I Error in the Evaluation of Scaled Average Bioequivalence, and a Method for its Control. Pharm Res. 2016; 33(11): 2805–14. doi:10.1007/s11095-016-2006-1.↩︎

  27. Molins E, Cobo E, Ocaña J. Two-Stage Designs Versus European Scaled Average Designs in Bioequivalence Studies for Highly Variable Drugs: Which to Choose? Stat Med. 2017: 36(30); 4777–88. doi:10.1002/sim.7452.↩︎

  28. World Health Organization. Application of reference-scaled criteria for AUC in bioequivalence studies conducted for submission to PQTm. Geneva. 22 November 2018.↩︎

  29. Food and Drug Administration. Office of Generic Drugs. Draft Guidance on Warfarin Sodium. Recommended Dec 2012.↩︎