Learn R Programming

expirest (version 0.1.5)

expirest_wisle: What-if (approach for) shelf life estimation (wisle)

Description

Based on a linear regression model fitted to a stability data set the function expirest_wisle() estimates the shelf life, or retest period, for the specified release and specification limit following the ARGPM guidance “Stability testing for prescription medicines”. The abbreviation “wisle” stands for “what-if shelf life estimation” (because it estimates the shelf life (“what”) for a given release limit (“if”)).

Usage

expirest_wisle(
  data,
  response_vbl,
  time_vbl,
  batch_vbl,
  rl,
  rl_sf,
  sl,
  sl_sf,
  srch_range,
  alpha = 0.05,
  alpha_pool = 0.25,
  xform = c("no", "no"),
  shift = c(0, 0),
  sf_option = "loose",
  ivl = "confidence",
  ivl_type = "one.sided",
  ivl_side = "lower",
  ...
)

Value

An object of class ‘expirest_wisle’ 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 alpha, alpha.pool, ivl, ivl.type and ivl.side.

Variables

A list of the variable names, i.e. the original names of batch_vbl, time_vbl and response_vbl and, if applicable, of the transformed variables.

Model.Type

A list of five elements specifying which model, based on the ANCOVA analysis, suits best. The first element (type.spec) is a numeric vector of length 2 specifying the best model accepted at the significance level of 0.25. The first number represents the decision on the intercept and the second on the slope, where 1 stands for “common” and 2 stands for “different”.

Models

A list of four elements named cics, dics, dids and individual. The first three elements contain the ‘lm’ objects of the “common intercept / common slope” (cics), “different intercept / common slope” (dics) and “different intercept / different slope” (dids) models. The fourth element is a list of the ‘lm’ objects of the models obtained from fitting the data of each batch individually.

AIC

A numeric named vector of the Akaike Information Criterion (AIC) values of each of the three fitted models.

BIC

A numeric named vector of the Bayesian Information Criterion (BIC) values of each of the three fitted models.

wc.icpt

A data frame of the worst case intercepts of each of the three fitted models.

wc.batch

A list of numeric value(s) of the worst case batch(es) per model type. In case of the dids model type, the estimation is done using the models obtained from fitting the data of each batch individually.

Limits

A list of all limits.

POI

A data frame of the intercepts, the differences between release and shelf life limits, the WCSLs, the expiry and release specification limits, the shelf lives and POI values. In case of the dids model type, the estimation of the POI values is done using the models obtained from fitting the data of each batch individually.

The POI data frame has the following columns:

Intercept.cics

The intercept of the worst case batch for the cics model.

Intercept.dics

The intercept of the worst case batch for the dics model.

Intercept.dids

The intercept of the worst case batch for the dids model.

Delta.cics

Absolute difference between the release and and the shelf life specification for the cics model.

Delta.dics

Absolute difference between the release and and the shelf life specification for the dics model.

Delta.dids

Absolute difference between the release and and the shelf life specification for the dids model.

WCSL.cics

WCSL for the cics model.

WCSL.dics

WCSL for the dics model.

WCSL.dids

WCSL for the dids model.

Exp.Spec

The (expiry) specification, i.e. the specification which is relevant for the determination of the expiry.

Rel.Spec

The calculated release specification.

Shelf.Life.cics

The estiamted shelf life for the cics model.

Shelf.Life.dics

The estiamted shelf life for the dics model.

Shelf.Life.dids

The estiamted shelf life for the dids model.

POI.Model.cics

The POI of the cics model.

POI.Model.dics

The POI of the dics model.

POI.Model.dids

The POI of the dids model.

Arguments

data

A data frame with the columns specified by response_vbl, time_vbl and batch_vbl.

response_vbl

A character string specifying the response variable name that must be a column of data.

time_vbl

A character string specifying the time variable name that must be a column of data.

batch_vbl

A character string specifying the column in data with the grouping information (i.e. a factorial variable) for the differentiation of the observations of the different batches.

rl

A numeric value or a numeric vector specifying the release specification limit(s) for which the corresponding expiry should be estimated.

rl_sf

A positive integer or a vector of positive integers specifying the number of “significant figures” (sf) of rl. It must have the same length as rl.

sl

A numeric value or a numeric vector of length 2 specifying the specification limit or limits. If a vector is provided it must be of the form c(lower limit, upper limit).

sl_sf

A positive integer or a vector of positive integers specifying the number of “significant figures” (sf) of sl. It must have the same length as sl.

srch_range

A vector of length 2 specifying the end-points of the (time) range that is supposed to contain the shelf life or retest period.

alpha

A numeric value between 0 and 1 specifying the significance level for the calculation of confidence or prediction intervals. The default is 0.05.

alpha_pool

A numeric value between 0 and 1 specifying the type I error rate for the test of the poolability of the batches. The default is 0.25, following ICH Q1E guideline. The value should not be changed unless supported by well-founded reasons.

xform

A vector of two character strings specifying the transformation of the response and the time variable. The default is “no” transformation, i.e. c("no", "no"), where the first element specifies the transformation of the \(x\) variable and the second element the transformation of the \(y\) variable. Valid alternatives for \(x\) and/or \(y\) variable transformation are "log" (natural logarithm), "sqrt" (square root) and "sq" (square).

shift

A vector of two values which will be added to the variables \(x\) and/or \(y\) before they are transformed as specified by the xform parameter, where the first element will be added to the \(x\) variable and the second element to the \(y\) variable. The purpose is to prevent an undefined state which could arise when variables with values of \(\leq 0\) are log or square root transformed. The default is c(0, 0).

sf_option

A character string specifying if the limits (rl or sl) should be regarded as “tight” or “loose”, i.e. either "tight" or "loose", respectively. The option "tight" means that the limits are rounded to the specified number of significant figures specified by the parameters rl_sf and sl_sf. In case of the option "loose" the limits are rounded to the specified number of significant figures (\(n\)), followed by the subtraction of \(1\) from the \(n^{th}\) digit and addition of \(5\) to the \((n + 1)^{th}\) digit if ivl_side is "lower", or followed by the addition of \(4\) to the \((n + 1)^{th}\) digit if ivl_side is "upper".

ivl

A character string of either "confidence" or "prediction", i.e. specifying the type of interval of interest. The default is "confidence".

ivl_type

A character string specifying if a “one sided” or a “two sided” interval should be calculated, i.e. either "one.sided" or "two.sided", respectively. The default is "one.sided".

ivl_side

A character string specifying if the “upper” or the “lower” limit is the relevant limit, i.e. either "upper" or "lower", respectively. The default is "lower".

...

Additional named or unnamed arguments passed on to uniroot().

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 has 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.

These requirements can be checked by aid of an “ANalysis of COVAriance” (ANCOVA) including the batch variable as 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.

Details

For the shelf life estimation for submissions in Australia the Australian Regulatory Guidelines for Prescription Medicines (ARGPM), i.e. the guidance “Stability testing for prescription medicines”, is binding. In chapter 14.3.1, “Predicting shelf life from stability data”, it is described how the estimation should be done. It recommends to take the worst case situation at batch release into account. The following examples are listed:

1a)

For medicine that has a lower Assay release limit of 95 per cent and a lower assay expiry limit of 90 per cent, the maximum decrease in assay allowed over the shelf-life is 5 per cent.

2a)

Similarly, for a medicine that has a release limit for an individual impurity of 0.2 per cent and an expiry limit of 0.5 per cent, the maximum increase in the impurity allowed over the shelf life is 0.3 per cent.

1b)

For the same medicine, if the actual release assay result is 101 per cent, then the shelf life should be determined at the time the medicine (or confidence interval of the regression line) decreases by 5 per cent and reaches 96 per cent, rather than the expiry limit (90 per cent). This takes into account the possibility of batches being released at the lower release limit (i.e. 95 per cent) and ensures they will comply with the expiry limit throughout the shelf life.

2b)

Similarly, if the actual impurity content is 0.1 per cent at batch release, the shelf life should be determined as the time the 95 per cent confidence interval reaches 0.4 per cent (i.e. increases by 0.3 per cent).

Consequently, it is necessary to define

  • a release limit and

  • an expiry limit or shelf life limit (usually the specification limit).

If both of these limits were the same the shelf life would be zero, i.e. no change allowed.

For the estimation of the shelf life or expiry limit it is necessary to find the point where the upper or lower 95% confidence interval limit of the linear model fitted to the data (by aid of lm) intersects the “worst case scenario limit” (WCSL), which is defined by the ARGPM guidance “Stability testing for prescription medicines” as the intercept \(\pm\) difference between the specification limit and the release limit, where this differences is added (\(+\)) if the upper limit is relevant or it is subtracted (\(-\)) if the lower limit is relevant. In this package, this point is called the “point of intersection” or “point of interest”, abbreviated POI.

Before performing the retest period or shelf life estimation 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.

References

Therapeutic Goods Administration (TGA) of the Department of Health of the Australian Government, Australian Regulatory Guidelines for Prescription Medicines (ARGPM), Stability testing for prescription medicines, Version 1.1, March 2017

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_osle, find_poi, uniroot, lm, AIC, BIC.

Examples

Run this code
# Potency stability data (in % of label claim (LC)) of five batches of a drug
# product obtained over a 24 months period:
str(exp1)

# 'data.frame':	53 obs. of  3 variables:
# $ Batch  : Factor w/ 6 levels "b2","b3","b4",..: 1 1 1 1 1 1 1 1 1 1 ...
# $ Month  : num  0 1 3 3 6 6 12 12 24 24 ...
# $ Potency: num  101 101.3 99.8 99.2 99.5 ...

# Successful estimations
res1 <-
  expirest_wisle(data = exp1[exp1$Batch %in% c("b2", "b5", "b7"), ],
                 response_vbl = "Potency", time_vbl = "Month",
                 batch_vbl = "Batch", rl = 98, rl_sf = 3, sl = 95,
                 sl_sf = 3, srch_range = c(0, 500))
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
#  Intercept.cics Intercept.dics Intercept.dids Delta.cics Delta.dics
#        100.5669       100.3638       100.2491          3          3
#  Delta.dids WCSL.cics WCSL.dics WCSL.dids Exp.Spec.Report Exp.Spec
#           3  97.56688  97.36375  97.24914              95    94.95
#  Rel.Spec.Report Rel.Spec Shelf.Life.cics Shelf.Life.dics Shelf.Life.dids
#               98    97.95        14.07398        13.23176        13.34561
#  POI.Model.cics POI.Model.dics POI.Model.dids
#         26.2241        24.8003       23.34184

res2 <-
  expirest_wisle(data = exp1[exp1$Batch %in% c("b4", "b5", "b8"), ],
                 response_vbl = "Potency", time_vbl = "Month",
                 batch_vbl = "Batch", rl = 98, rl_sf = 3, sl = 95,
                 sl_sf = 3, srch_range = c(0, 500))
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
#  Intercept.cics Intercept.dics Intercept.dids Delta.cics Delta.dics
#        101.5498       100.4882       101.2594          3          3
#  Delta.dids WCSL.cics WCSL.dics WCSL.dids Exp.Spec.Report Exp.Spec
#           3  98.54976  97.48822  98.25938              95    94.95
#  Rel.Spec.Report Rel.Spec Shelf.Life.cics Shelf.Life.dics Shelf.Life.dids
#               98    97.95        13.03332        11.42141        7.619661
#  POI.Model.cics POI.Model.dics POI.Model.dids
#        28.12518       22.47939       15.96453

# Unsuccessful estimation
res3 <-
  expirest_wisle(data = exp1[exp1$Batch %in% c("b2", "b5", "b7"), ],
                 response_vbl = "Potency", time_vbl = "Month",
                 batch_vbl = "Batch", rl = 98, rl_sf = 3, sl = 95,
                 sl_sf = 3, srch_range = c(0, 500), alpha = 1E-16)
res3$POI

# (Expected) results in res3$POI
#  Intercept.cics Intercept.dics Intercept.dids Delta.cics Delta.dics
#        100.5669             NA             NA          3         NA
#  Delta.dids WCSL.cics WCSL.dics WCSL.dids Exp.Spec.Report Exp.Spec
#          NA  97.56688        NA        NA              95    94.95
#  Rel.Spec.Report Rel.Spec Shelf.Life.cics Shelf.Life.dics Shelf.Life.dids
#               98    97.95              NA              NA              NA
#  POI.Model.cics POI.Model.dics POI.Model.dids
#        14.42089       2.480635             NA

# Estimation may also fail because of an inappropriate 'srch-range' setting.
res4 <-
  expirest_wisle(data = exp1[exp1$Batch %in% c("b2", "b5", "b7"), ],
                 response_vbl = "Potency", time_vbl = "Month",
                 batch_vbl = "Batch", rl = 98, rl_sf = 3, sl = 95,
                 sl_sf = 3, srch_range = c(0, 5))
res4$POI

# (Expected) results in res4$POI
#  Intercept.cics Intercept.dics Intercept.dids Delta.cics Delta.dics
#        100.5669             NA             NA          3         NA
#  Delta.dids WCSL.cics WCSL.dics WCSL.dids Exp.Spec.Report Exp.Spec
#          NA  97.56688        NA        NA              95    94.95
#  Rel.Spec.Report Rel.Spec Shelf.Life.cics Shelf.Life.dics Shelf.Life.dids
#               98    97.95              NA              NA              NA
#  POI.Model.cics POI.Model.dics POI.Model.dids
#              NA             NA             NA

Run the code above in your browser using DataLab