mztia {disprofas} | R Documentation |
Martinez & Zhao Tolerance Interval Approach
Description
The Martinez & Zhao Tolerance Interval Approach (mztia
) is a
simple approach for the comparison of dissolution profiles. The
mztia()
function calculates tolerance intervals (TI) at each time
point of the dissolution profiles of a set of reference batches. By aid
of a graphical display the test batches are checked to lie within the TI
boundaries or within certain limits exceeding the TI boundaries by a
specified percentage.
Usage
mztia(
data,
shape,
tcol,
grouping,
reference,
response = NULL,
alpha = 0.05,
P = 0.99,
cap = TRUE,
bounds = c(0, 100),
QS = c(5, 15),
...
)
Arguments
data |
A data frame with the dissolution profile data in wide or in
long format (see parameter |
shape |
A character string specifying if the data frame is in long or in wide format. |
tcol |
If |
grouping |
A character string specifying the column in |
reference |
A character string specifying the name of the reference
group from the |
response |
A character string that is expected if |
alpha |
A numeric value between 0 and 1 specifying the probability
level. The default is |
P |
A numeric value between 0 and 1 specifying the proportion of the
population being enclosed by the tolerance interval boundaries. The
default is |
cap |
A logical variable specifying if the calculated tolerance limits
should be limited (i.e. capped). The default is |
bounds |
A numeric vector of the form |
QS |
A numeric vector of the form |
... |
Further arguments passed on to the |
Details
The tolerance interval approach proposed by Martinez & Zhao (2018)
is a simple approach for the comparison of dissolution profiles. The authors
propose to calculate for each time point of a set of reference dissolution
profiles a tolerance interval (TI
), i.e. intervals containing P
%
of the population of potential values for reference product at a probability
level of alpha / 2
per tail (i.e., (1 - alpha) 100
% confidence).
Based on these TI
s the dissolution profiles of the test batch(es) is
(are) compared, i.e. the corresponding data points should lie within the
TI
s. The TI
s are calculated as
Y_{utl,ltl} = \bar{Y} \pm k \times s
where \bar{Y}
is the average, s
is the sample standard
deviation, and the factor k
is calculated according to Hahn (Hahn &
Meeker (1991)), as proposed in Martinez & Zhao (2018).
Since the goal of the comparison is not to confirm simply
“statistical sameness” but “product comparability”,
Martinez & Zhao propose allowing acceptable deviations by utilizing the
concepts described by the United States Pharmacopoeia (USP), chapter <711>
on dissolution, defining allowable deviations from a set of product
specifications (Q
). The TI
s serve as the target value Q
at each sampling time. The allowable deviations about Q
are defined
by the S1
and S2
acceptance criteria of USP chapter <711> on
dissolution:
The
S1
level boundary is defined byQ \pm 5
% at each time point. For every 12 profiles tested, only one profile is allowed to exceed theS1
bounds.The
S2
level boundary is defined byQ \pm 15
% at each time point. No observation from any of the test dissolution profiles is allowed to exceed theS2
bounds.
In situations where the reference formulation itself has more than one of
twelve observations (profiles) exceeding S1
at one or more time points,
additional runs of the reference product must be performed. It is deemed
appropriate to use the same values of S1
and S2
across all time
points because the high variability associated with the early sampling times
is already factored into the TI
s.
TI
calculation according to Hahn is proposed because it appeared to be
more numerically stable and gave more consistent TI
s than the TI
calculation method proposed by Howe (Howe 1969) when samples were very
variable. The reason might be due to the less stringent requirements
imposed by Hahn's method with respect to the normality of the data.
Value
An object of class ‘mztia
’ is returned, containing the
following elements:
Variables |
A list of the variables and the corresponding values. |
Limits |
A data frame of the limits calculated for each time point. |
Data |
A data frame consisting of the provided data, complemented by the calculated tolerance interval results. |
Profile.TP |
If |
References
Martinez, M.N., and Zhao, X. A simple approach for comparing the
in vitro dissolution profiles of highly variable drug products: a
proposal. AAPS Journal. (2018); 20: 78.
doi: 10.1208/s12248-018-0238-1
Howe, W.G. Two-sided tolerance limits for normal populations - some
improvements. J Am Stat Assoc. (1969); 64: 610-620.
doi: 10.1080/01621459.1969.10500999
Hahn, G.J., and Meeker, W. Q. Statistical intervals: A guide for
practitioners. (1991); John Wiley & Sons, New York.
Hahn's method is also described in: SAS/QC 13.1: User's Guide. Chapter 5,
sub-chapter “Details: INTERVALS Statement”, pp 421-424. SAS Institute
Inc. 2013. Cary, NC.
https://support.sas.com/documentation/cdl/en/qcug/66857/PDF/default/qcug.pdf
U.S. Pharmacopoeia. 2016 U.S. Pharmacopoeia-National Formulary (USP 39 NF 34). Volume 1. Rockville, Md: United States Pharmacopeial Convention, Inc; 2015. <711> Dissolution.
See Also
Examples
# Fluid weights of 100 drink cans were measured in ounces:
str(dip5)
# 'data.frame': 100 obs. of 3 variables:
# $ type : Factor w/ 1 level "reference": 1 1 1 1 1 1 1 1 1 1 ...
# $ batch : Factor w/ 100 levels "b1","b10","b100",..: 1 13 24 35 46 57 68 ...
# $ weight: num 12.1 12 12 12 12 ...
# Calculation of tolerance intervals
m_alpha_P <- matrix(c(rep(c(0.01, 0.05, 0.1), each = 3),
1 - rep(c(0.1, 0.05, 0.01), times = 3)),
ncol = 2, byrow = FALSE)
ll <-
apply(m_alpha_P, MARGIN = 1, FUN = function(x)
mztia(data = dip5, shape = "long", tcol = 1, grouping = "type",
reference = "reference", response = "weight", alpha = x[1],
P = x[2], cap = FALSE)[["Data"]][102, "weight"])
ul <-
apply(m_alpha_P, MARGIN = 1, FUN = function(x)
mztia(data = dip5, shape = "long", tcol = 1, grouping = "type",
reference = "reference", response = "weight", alpha = x[1],
P = x[2], cap = FALSE)[["Data"]][103, "weight"])
# Expected results in ll and ul
rbind(ll, ul)
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
# ll 11.91648 11.8987 11.86395 11.92132 11.90446 11.87152 11.92373 11.90734
# ul 12.10212 12.1199 12.15465 12.09728 12.11414 12.14708 12.09487 12.11126
# [,9]
# ll 11.8753
# ul 12.1433
# Use a data frame in wide format
# Dissolution data of one reference batch and one test batch of n = 6
# tablets each:
str(dip1)
# 'data.frame': 12 obs. of 10 variables:
# $ type : Factor w/ 2 levels "R","T": 1 1 1 1 1 1 2 2 2 2 ...
# $ tablet: Factor w/ 6 levels "1","2","3","4",..: 1 2 3 4 5 6 1 2 3 4 ...
# $ t.5 : num 42.1 44.2 45.6 48.5 50.5 ...
# $ t.10 : num 59.9 60.2 55.8 60.4 61.8 ...
# $ t.15 : num 65.6 67.2 65.6 66.5 69.1 ...
# $ t.20 : num 71.8 70.8 70.5 73.1 72.8 ...
# $ t.30 : num 77.8 76.1 76.9 78.5 79 ...
# $ t.60 : num 85.7 83.3 83.9 85 86.9 ...
# $ t.90 : num 93.1 88 86.8 88 89.7 ...
# $ t.120 : num 94.2 89.6 90.1 93.4 90.8 ...
# Using the defaults; Limits are capped to the range specified by 'bounds'
res1 <- mztia(data = dip1, shape = "wide", tcol = 3:10, grouping = "type",
reference = "R")
res1$Limits
# Expected results in res1$Limits
# Time Mean LTL UTL S1.LTL S1.UTL S2.LTL S2.UTL
# 1 5 46.77167 27.22641 66.31693 22.22641 71.31693 12.22641 81.31693
# 2 10 60.13333 46.15483 74.11184 41.15483 79.11184 31.15483 89.11184
# 3 15 67.27500 56.90417 77.64583 51.90417 82.64583 41.90417 92.64583
# 4 20 71.98667 65.44354 78.52979 60.44354 83.52979 50.44354 93.52979
# 5 30 78.07000 69.54259 86.59741 64.54259 91.59741 54.54259 101.59741
# 6 60 84.81667 77.20275 92.43058 72.20275 97.43058 62.20275 107.43058
# 7 90 89.09333 76.24588 100.00000 71.24588 105.00000 61.24588 115.00000
# 8 120 91.43833 80.29321 100.00000 75.29321 105.00000 65.29321 115.00000
# Without capping of limits to 105%
res2 <- mztia(data = dip1, shape = "wide", tcol = 3:10, grouping = "type",
reference = "R", cap = FALSE)
res2$Limits
# Expected results in res1$Limits
# Time Mean LTL UTL S1.LTL S1.UTL S2.LTL S2.UTL
# 1 5 46.77167 27.22641 66.31693 22.22641 71.31693 12.22641 81.31693
# 2 10 60.13333 46.15483 74.11184 41.15483 79.11184 31.15483 89.11184
# 3 15 67.27500 56.90417 77.64583 51.90417 82.64583 41.90417 92.64583
# 4 20 71.98667 65.44354 78.52979 60.44354 83.52979 50.44354 93.52979
# 5 30 78.07000 69.54259 86.59741 64.54259 91.59741 54.54259 101.59741
# 6 60 84.81667 77.20275 92.43058 72.20275 97.43058 62.20275 107.43058
# 7 90 89.09333 76.24588 101.94079 71.24588 106.94079 61.24588 116.94079
# 8 120 91.43833 80.29321 102.58346 75.29321 107.58346 65.29321 117.58346
# Tolerance intervals are calculated exclusively for the level of the
# grouping variable that is specified by the reference variable. Therefore,
# the following code produces the same limits summary as in res2$Limits.
tmp <- rbind(dip1,
data.frame(type = "T2",
tablet = as.factor(1:6),
dip1[7:12, 3:10]))
res2 <- mztia(data = dip1, shape = "wide", tcol = 3:10, grouping = "type",
reference = "R", cap = FALSE)
res3 <- mztia(data = tmp, shape = "wide", tcol = 3:10, grouping = "type",
reference = "R", cap = FALSE)
isTRUE(all.equal(res2$Limits, res3$Limits))
# [1] TRUE