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 (\textit{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 \textit{TI}
boundaries or within certain limits exceeding
the \textit{TI}
boundaries by a specified percentage.
Usage
mztia(
data,
shape,
tcol,
grouping,
reference,
response = NULL,
na_rm = FALSE,
alpha = 0.05,
pp = 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 that indicates whether the data frame is in long or in wide format. |
tcol |
If |
grouping |
A character string that specifies the column in |
reference |
A character string that specifies the name of the reference
group from the |
response |
A character string that is expected if |
na_rm |
A logical value that indicates whether observations containing
|
alpha |
A numeric value between 0 and 1 that specifies the probability
level. The default is |
pp |
A numeric value between 0 and 1 that specifies the proportion of
the population being enclosed by the tolerance interval boundaries. The
default is |
cap |
A logical variable that indicates whether 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 (\textit{TI}
), i.e. intervals containing
pp
% 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 \textit{TI}
s the dissolution profiles of
the test batch(es) is (are) compared, i.e. the corresponding data points
should lie within the \textit{TI}
s. The \textit{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 \textit{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 \textit{TI}
s.
\textit{TI}
calculation according to Hahn is proposed because it
appeared to be more numerically stable and gave more consistent
\textit{TI}
s than the \textit{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
# 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", na_rm = FALSE,
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", na_rm = FALSE,
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
# 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