expirest_osle {expirest} | R Documentation |
Ordinary shelf life estimation (osle)
Description
Based on a linear regression model fitted to a stability data set the
function expirest_osle()
estimates the shelf life, or retest period,
following the ICH Q1E guideline. The abbreviation “osle” stands for
“ordinary shelf life estimation”.
Usage
expirest_osle(
data,
response_vbl,
time_vbl,
batch_vbl,
sl,
sl_sf,
srch_range,
alpha = 0.05,
alpha_pool = 0.25,
xform = c("no", "no"),
shift = c(0, 0),
sf_option = "tight",
ivl = "confidence",
ivl_type = "one.sided",
ivl_side = "lower",
...
)
Arguments
data |
A data frame with the columns specified by |
response_vbl |
A character string that specifies the response variable
name that must be a column of |
time_vbl |
A character string that specifies the time variable name
that must be a column of |
batch_vbl |
A character string that specifies the column in |
sl |
A numeric value or a numeric vector of length |
sl_sf |
A positive integer or a vector of positive integers that
specifies the number of “significant figures” (sf) of |
srch_range |
A vector of length |
alpha |
A numeric value between 0 and 1 that specifies the significance
level for the calculation of confidence or prediction intervals. The
default is |
alpha_pool |
A numeric value between 0 and 1 that specifies the type I
error rate for the test of the poolability of the batches. The default
is |
xform |
A vector of two character strings that specifies the
transformation of the response and the time variable. The default is
“no” transformation, i.e. |
shift |
A vector of two values which will be added to the variables
|
sf_option |
A character string that specifies if the limits ( |
ivl |
A character string of either |
ivl_type |
A character string that specifies if a “one sided”
or a “two sided” interval should be calculated, i.e. either
|
ivl_side |
A character string that specifies if the specification
limit, given that the limit has only one side, is an “upper” or a
“lower” bound, i.e. it is specified as either |
... |
Additional named or unnamed arguments passed on to
|
Details
According to ICH Q1E guideline, “an appropriate approach to retest period or shelf life estimation is to analyse a quantitative attribute by determining the earliest time at which the 95 percent confidence limit for the mean intersects the proposed acceptance criterion” (in this package, this point is called the “point of intersection” (POI)). Furthermore, it says that “for an attribute known to increase with time, the upper one-sided 95 percent confidence limit should be compared to the acceptance criterion. For an attribute that can either increase or decrease, or whose direction of change is not known, two-sided 95 percent confidence limits should be calculated and compared to the upper and lower acceptance criteria.” The approach can be used to estimate the retest period or shelf life for a single batch or for multiple batches. According to the guideline, “for a drug substance or for a drug product available in a single strength and a single container size and/or fill, the retest period or shelf life is generally estimated based on the stability data from a minimum of three batches.”
Before performing the retest period or shelf life estimation with results from multiple batches, the most suitable model should be determined. It should particularly be verified if data of all test batches are poolable or not. Details on this are described in section “Checking batch poolability” below.
Value
An object of class ‘expirest_osle
’ is returned,
containing the following elements:
Data |
Data frame of the original data including new columns with transformed variables, if applicable. |
Parameters |
A list of the parameters with the elements |
Variables |
A list of the variable names, i.e. the original names of
|
Model.Type |
A list of two elements that specifies which model, based
on the ANCOVA analysis, suits best. The first element ( |
Models |
A list of four elements named |
AIC |
A numeric named vector of the Akaike Information Criterion (AIC)
values of the |
BIC |
A numeric named vector of the Bayesian Information Criterion (BIC)
values of each of the |
wc.icpt |
A numeric named vector of the worst case intercepts. The
information about which limit the corresponding confidence interval
crosses is stored in the attribute named |
wc.batch |
A numeric named vector of the batches with the worst case
intercepts. The information about which limit the corresponding confidence
interval crosses is stored in the attribute named |
Limits |
A list of all limits. |
Intercepts |
A list of the intercepts of all models. |
All.POI |
A list of two elements named |
POI |
A numeric named vector of the POI values of the worst case
batches of each model. The information about which limit the corresponding
confidence interval crosses is stored in the attribute named |
Checking batch poolability
According to ICH Q1E guideline, construction of the 95% confidence interval
on the basis of the combined data of all test batches is allowed only if it
has been confirmed by aid of a statistical test whether the regression lines
from the different batches have a common slope and a common intercept. A
significance level of alpha_pool = 0.25
should to be used for both
batch-related terms, and the test of the slopes has to precede the test of
the intercepts. From these tests, three possible models may be appropriate,
i.e.
a common intercept / common slope model (cics),
a different intercept / common slope model (dics) or
a different intercept / different slope model (dids).
The common intercept / different slope model is not of practical relevance because the corresponding model is missing an effect. If the slopes are significantly different, there is no point comparing intercepts. The dids model has individual intercepts and individual slopes, and the calculation of confidence intervals is based on the corresponding individual mean square errors. The different intercept / different slope model where the mean square error is pooled across batches is reported as dids.pmse.
These requirements can be checked by aid of an “ANalysis of
COVAriance” (ANCOVA) including the batch variable as main effect and as
batch \times time
interaction term. The full ANCOVA model
simultaneously tests all the effects, and non-significant effects can be
identified and removed for fitting of the final regression model that is
used for the estimation of the shelf life or retest period.
The significance level (alpha_pool = 0.25
, Type I error) is used to
increase the power of the test to detect cases where the data should not be
pooled. Setting alpha_pool = 0.25
decreases the probability of
incorrectly concluding that stability data from multiple batches can be
pooled. On the other hand, though, it increases the probability of using a
single batch to determine expiry when pooling batches would be more
appropriate.
References
International Council for Harmonisation of Technical Requirements for Registration of Pharmaceuticals for Human (ICH), Harmonised Tripartite Guideline, Evaluation of Stability Data Q1E, step 4, February 2003 (CPMP/ICH/420/02).
See Also
expirest_wisle
, uniroot
,
lm
, AIC
, BIC
.
Examples
# Successful estimations
# A model with common intercepts / common slopes (cics)
res1 <-
expirest_osle(data = exp1[exp1$Batch %in% c("b2", "b5", "b7"), ],
response_vbl = "Potency", time_vbl = "Month",
batch_vbl = "Batch", sl = 95, sl_sf = 3,
srch_range = c(0, 500), sf_option = "loose")
res1$Model.Type
res1$POI
# Expected results in res1$Model.Type
# $type.spec
# common.icpt common.slp
# 1 1
#
# $type.acronym
# [1] "cics"
# Expected results in res1$POI
# cics dics dids.pmse dids
# 26.22410 24.80030 23.66724 23.34184
# attr(,"side")
# cics dics dids.pmse dids
# "lower" "lower" "lower" "lower"
# The parameter settings sf_option = "loose" and ivl_side = "lower" (the
# default setting of ivl_side) cause the specification limit of 95.0
# (sl_sf = 3, i.e. 3 significant digits) to be reduced by 0.05, i.e. the
# actual specification limit is 94.95.
# A model with different intercepts / different slopes (dids)
res2 <-
expirest_osle(data = exp1[exp1$Batch %in% c("b4", "b5", "b8"), ],
response_vbl = "Potency", time_vbl = "Month",
batch_vbl = "Batch", sl = 95, sl_sf = 3,
srch_range = c(0, 500), sf_option = "loose")
res2$Model.Type
res2$POI
# Expected results in res2$Model.Type
# $type.spec
# common.icpt common.slp
# 0 0
#
# $type.acronym
# [1] "dids"
# Expected results in res2$POI
# cics dics dids.pmse dids
# 28.12518 22.47939 15.72348 15.96453
# attr(,"side")
# cics dics dids.pmse dids
# "lower" "lower" "lower" "lower"
# Estimation where it is not know a priori which limit is crossed first, i.e.
# letting the estimation be done for both specification limits.
res3 <-
expirest_osle(
data = exp3, response_vbl = "Moisture", time_vbl = "Month",
batch_vbl = "Batch", sl = c(1.5, 3.5), sl_sf = c(2, 2),
srch_range = c(0, 500), sf_option = "loose", ivl = "confidence",
ivl_type = "two.sided", ivl_side = "both")
res3$Model.Type
res3$POI
# Expected results in res3$Model.Type
# $type.spec
# common.icpt common.slp
# 1 1
#
# $type.acronym
# [1] "cics"
# Expected results in res3$POI
# cics dics dids.pmse dids
# 46.85172 41.84802 22.41808 22.50966
# attr(,"side")
# cics dics dids.pmse dids
# "upper" "upper" "upper" "lower"
# The parameter settings sf_option = "loose" and ivl_side = "both" (the
# default setting of ivl_side) cause the specification limits of 1.5 and 3.5
# (sl_sf = 2, i.e. 2 significant digits) to be reduced by 0.05 and increased
# by 0.04, respectively, i.e. the actual specification limits are 1.45 and
# 3.54, respectively.
# Analysis with a single batch
res4 <-
expirest_osle(
data = exp3[exp3$Batch == "b1", ], response_vbl = "Moisture",
time_vbl = "Month", batch_vbl = "Batch", sl = c(1.5, 3.5),
sl_sf = c(2, 2), srch_range = c(0, 500), sf_option = "tight",
ivl = "confidence", ivl_type = "two.sided", ivl_side = "both")
# Since only one batch is involved there is no model type. Nevertheless, the
# result is reported under the dids model name.
res4$Model.Type
res4$POI
# Expected results in res4$Model.Type
# $type.spec
# common.icpt common.slp
# NA NA
#
# $type.acronym
# [1] "n.a."
# Expected results in res4$POI
# cics dics dids.pmse dids
# NA NA NA 21.42596
# attr(,"side")
# cics dics dids.pmse dids
# "NA" "NA" "NA" "lower"
# Unsuccessful estimations
## Not run:
# Intervals are wider than the specification limits (no intersection).
res5 <-
expirest_osle(
data = exp3, response_vbl = "Moisture", time_vbl = "Month",
batch_vbl = "Batch", sl = 1.5, sl_sf = 2, srch_range = c(0, 500),
sf_option = "tight", ivl = "prediction", ivl_type = "two.sided",
ivl_side = "lower")
res5$POI
# (Expected) results in res5$POI
# cics dics dids.pmse dids
# NA NA NA NA
# attr(,"side")
# cics dics dids.pmse dids
# "lower" "lower" "lower" "lower"
# Estimation may also fail because of an inappropriate 'srch_range' setting.
res6 <-
expirest_osle(data = exp1[exp1$Batch %in% c("b2", "b5", "b7"), ],
response_vbl = "Potency", time_vbl = "Month",
batch_vbl = "Batch", sl = 95, sl_sf = 3,
srch_range = c(0, 5))
res6$POI
# (Expected) results in res6$POI
# cics dics dids.pmse dids
# NA NA NA NA
# attr(,"side")
# cics dics dids.pmse dids
# "lower" "lower" "lower" "lower"
## End(Not run)