Bioequivalence

**Bioequivalence vs
Non-inferiority vs Inferiority**

When
conducting a clinical trial, a hypothesis of interest needs to be identified and
defined. Various statistical techniques can be used to address the chosen
hypothesis, depending on the type of comparison that is being made. The most
common comparison is between the effects of a new treatment compared to the
current treatment. That said, the specific comparison of interest will shape
the hypothesis and in turn, the statistical method required.

There
are three possible hypothesis that can be formulated when comparing two
treatments:

**1.
**The new treatment is at least as effective
as the current treatment (non-inferiority)

**2.
**The new treatment is strictly more
effective than the current treatment (inferiority)

**3.
**The new treatment is equivalent to the
current treatment (bioequivalence)

While
these three possible hypothesis appear to be similar, they are slightly
different, and thus require slightly different statistical tests.

Non-inferiority
trails are used to test whether a minimum level of efficacy has been achieved
in the new treatment. These trials are
designed to show that the new treatment is no less effective than the existing
treatment.

Inferiority/superiority
trials are used to test whether the new treatment is strictly more effective
than the current treatment. These trials are designed to detect a difference
between treatments.

Bioequivalence
trials are used to test whether a new treatment is the same, within an
acceptable range, to the current treatment. These trials are designed to
confirm the absence of a meaningful difference between treatments.

Before
we define the hypothesis’ and their corresponding statistical test, it
important to identify the type of outcome variable that is of interest.

**Outcome Variable
Type**

**2.1
Binary Outcome**

*Unpaired
*

**Non-inferiority:**

vs

**Inferiority:**

** **vs** **

**Bioequivalence:**

vs

and

**Code Example in SAS (non-inferiority)**

/* Binary outcome */

/* Unpaired */

data table_unpair;

/* Data */

p1=0.4203;

p2=0.4638;

n1=69;n2=69;

/* Calculation */

theta=p1-p2;

var=(p1*(1-p1)/n1)+(p2*(1-p2)/n2);

se=sqrt(var);

delta=0.1; /* Pick a value of delta */

zright=(theta+delta)/se;
/* z-score for Non-inferiority */

zleft=(theta-delta)/se; /* z-score
for Inferiority */

pright=1-cdf("normal",zright); /* p-value for Non-inferiority */

pleft=cdf("normal",zleft); /* p-value for
Inferiority */

pboth=pright+pleft;
/* p-value for Bioequivalence */

run;

/* Paired */

data table;

/* Data */

p1=0.4203; *p1=proportion of 1 in protocol 1;

p2=0.4638; *p2=proportion of 1 in protocol 2;

p10=0;

p01=0.0435;

n=69;

/* Calculation */

theta=p1-p2;

var=(p10+p01-theta*theta)/n;

se=sqrt(var);

delta=0.1; /* Pick a value of delta */

zright=(theta+delta)/se;
*two-tailed test; /* z-score for Non-inferiority */

zleft=(theta-delta)/se;
*two-tailed test; /* z-score for Inferiority */

pright=1-cdf("normal",zright); /* p-value for
Non-inferiority */

pleft=cdf("normal",zleft); /* p-value for
Inferiority */

pboth=pright+pleft;
/* p-value for Bioequivalence */

run;

/* Continuous outcome */

/* Unpaired */

data Process;

input _STAT_ $4. @6 Process $3. @10 Quality Yield Waste;

cards;

N New 27 27 27

MEAN New 34.6667 50.0000 11.9889

STD
New 1.8605 0.8321 2.2548

N Old 27 27 27

MEAN Old 19.9530 40.1481 10.3556

STD
Old 0.8077 0.7698 2.1445

;

/* Non-inferiority */

proc ttest data=Process sides=U
h0=-0.1 /*delta*/ ;

class Process;

var Waste;

run;

/* Inferiority */

proc ttest data=Process sides=L
h0=0.1 /*delta*/ ;

class Process;

var Waste;

run;

/* Bioequivalence: p-value of Non-inferiority
+ p-value of Inferiority */

/* Paired */

DATA WEIGHT;

INPUT WBEFORE WAFTER;

DATALINES;

200 185

175 154

188 176

198 193

197 198

310 275

245 224

202 188

;

RUN;

/* Non-inferiority */

proc ttest data=WEIGHT sides=U
h0=-0.1 /*delta*/ ;

Paired WBEFORE * WAFTER;

run;

/* Inferiority */

proc ttest data=WEIGHT sides=L
h0=0.1 /*delta*/ ;

Paired WBEFORE * WAFTER;

run;

/* Bioequivalence: p-value of Non-inferiority + p-value of Inferiority */

**Code Example in R (non-inferiority)**

install.packages("tidyverse")

library(tidyverse)

# Binary

# Unpaired

p1=0.4203

p2=0.4638

theta=p1-p2

n1=69;n2=69

var=(p1*(1-p1)/n1)+(p2*(1-p2)/n2)

se=sqrt(var)

delta=0.1

zright=(theta+delta)/se

zleft=(theta-delta)/se

pright=1-pnorm(zright)

pleft=pnorm(zleft)

print(paste("Non-inferiority:
", "z-score:", zright,
"p-value:", pright))

print(paste("Inferiority:
", "z-score:", zleft,
"p-value:", pleft))

print(paste("Bioequivalence:
", "p-value:", pright+pleft))

# Paired

p1=0.4203

p2=0.4638

p10=0

p01=0.0435

theta=p1-p2

n=69

var=(p10+p01-theta*theta)/n

se=sqrt(var)

delta=0.1

zright=(theta+delta)/se

zleft=(theta-delta)/se

pright=1-pnorm(zright)

pleft=pnorm(zleft)

print(paste("Non-inferiority:
", "z-score:", zright,
"p-value:", pright))

print(paste("Inferiority:
", "z-score:", zleft,
"p-value:", pleft))

print(paste("Bioequivalence: ",
"p-value:", pright+pleft))

# Continuous

# Unpaired

# Data

process = data.frame(

process = c(rep("NEW",
27), rep("OLD", 27)),

quality = c(rnorm(27, 34.6667, 1.8605), rnorm(27, 19.9530, 0.8077)),

yield = c(rnorm(27, 50, 0.8321), rnorm(27, 40.1481, 0.7698)),

waste = c(rnorm(27, 11.9889, 2.2548), rnorm(27, 10.3556, 2.1445))

)

process_new = filter(process,
process == "NEW")

process_old = filter(process,
process == "OLD")

## Set a delta value

delta = 0.1

## Non-inferiority

t.test(process_new$waste, process_old$waste, mu = -delta, alternative =
"greater")

## Inferiority

t.test(process_new$waste, process_old$waste, mu = delta, alternative =
"less")

## Bioequivalence

p1 = t.test(process_new$waste, process_old$waste, mu = delta, alternative =
"less")$p.value

p2 = t.test(process_new$waste, process_old$waste, mu = -delta, alternative =
"greater")$p.value

print(paste("Bioequivalence
p-value: ", p1+p2))

# Paired

# Data

weight = data.frame(

wbefore
= c(200,175,188,198,197,310,245,202),

wafter = c(185,154,176,193,198,275,224,188)

)

## Non-inferiority

t.test(weight$wbefore, weight$wafter, paired = T, mu = -delta, alternative =
"greater")

## Inferiority

t.test(weight$wbefore, weight$wafter, paired = T, mu = delta, alternative =
"less")

## Bioequivalence

p1 = t.test(weight$wbefore, weight$wafter, paired = T, mu = delta, alternative =
"less")$p.value

p2 = t.test(weight$wbefore, weight$wafter, paired = T, mu = -delta, alternative =
"greater")$p.value

print(paste("Bioequivalence p-value: ", p1+p2))

References

**2.
**Althunian, T. A., de Boer, A., Groenwold, R. H. H., & Klungel, O.
H. (2017). Defining the noninferiority margin and analysing noninferiority: An overview. British Journal
of Clinical Pharmacology

**3.
**Committee for Proprietary Medicinal
Products. (2001). Points to consider on switching between superiority and
non-inferiority. British Journal of Clinical Pharmacology

**4.
**Tsong, Y., Zhang, J., & Levenson, M. (2007). Choice of δ
noninferiority margin and dependency of the noninferiority trials.
Journal of Biopharmaceutical Statistics

**5.
**Wang, B., Wang, H., Tu, X. M., & Feng, C. (2017). Comparisons of
Superiority, Non-inferiority, and Equivalence Trials. Shanghai Archives of
Psychiatry