Bioequivalence
Docstrings
Bioequivalence.Bioequivalence
— ModuleBioequivalence.jl
This module offers a suite of routines for bioequivalence (BE) analysis.
Bioequivalence.EMA_CMAX
— ConstantEMA_CMAX = [GeometricMeanRatioBounds(), AverageBioequivalenceWithExpandingLimits(0.76, CV_min = 0.3, CV_max = 0.5)]
Criteria for the European Medicines Agency average bioequivalence for Cmax endpoints.
Bioequivalence.EMA_NarrowTherapeuticIndex
— ConstantEMA_NarrowTherapeuticIndex = [AverageBioequivalenceWithExpandingLimits(0, lower_bound = 0.9, upper_bound = 1.11)]
Criteria for the European Medicines Agency narrow therapeutic index drugs.
Bioequivalence.FDA
— ConstantFDA = [GeometricMeanRatioBounds(), AverageBioequivalenceWithExpandingLimits((log(1.25) / 0.25)^2)]
Criteria for the U.S. Food and Drug Administration (non-narrow therapeutic index drugs):
If the within subject variability of the reference formulation is less than 30%, the unscaled confidence interval should pass the standard critertia: LB ≥ 80% ^ UB ≤ 125%. Otherwise, the 95% upper confidence bound for (T̄ₜ - Ȳᵣ)² - 𝜃 * σwᵣ² ≤ 0 (numbers should be kept to a minimum of four significant figures for comparison) with 𝜃 ≈ 0.7967 and 80% ≤ GMR ≤ 125%.
Bioequivalence.FDA_NarrowTherapeuticIndex
— ConstantFDA_NarrowTherapeuticIndex = [
AverageBioequivalenceWithExpandingLimits(0),
AverageBioequivalenceWithExpandingLimits((log(1 / 0.9) / 0.1)^2, CV_min = 0, CV_max = 0.2142),
WithinSubjectVariabilityRatio()
]
Criteria for the U.S. Food and Drug Administration Narrow Therapeutic Index drug:
a) The 95% upper confidence bound for (T̄ₜ - Ȳᵣ)² - 𝜃 * σwᵣ² ≤ 0 (numbers should be kept to a minimum of four significant figures for comparison). 𝜃 ≈ 1.11.
b) Regular unscaled bioequivalence limits of [80.00%, 125.00%] should be passed.
c) The proposed requirement for the upper limit of the 90% equal-tails confidence interval for σwₜ / σwᵣ ≤ 2.5.
Bioequivalence.NoAssessmentBioequivalenceCriterion
— ConstantNoAssessmentBioequivalenceCriterion
Indicates that no assessment is needed.
Bioequivalence.StandardBioequivalenceCriterion
— ConstantStandardBioequivalenceCriterion
Standard bioequivalence criterion: LB ≥ 80% ^ UB ≤ 125%.
Bioequivalence.AverageBioequivalenceWithExpandingLimits
— TypeAverageBioequivalenceWithExpandingLimits(
θ::Real = -1;
CV_min::Real = 0.3,
CV_max::Real = Inf,
lower_bound::Real = 0.8,
upper_bound::Real = 1.25
)
Criteria for the average bioequivalence acceptable bounds. If θ < 0, use the θ from the BioequivalenceEndpointOutput if available. If θ > 0, overwrite BioequivalenceEndpointOutput parameters in assessment. If θ == 0, use unscaled confidence interval with specified interval.
See also assess_be
Bioequivalence.BioequivalenceCriterion
— TypeBioequivalenceCriterion
An abstract bioequivalence criterion.
Bioequivalence.BioequivalenceEndpointOutput
— TypeBioequivalenceEndpointOutput
A bioequivalence study output object.
See also: pumas_be
.
Fields
endpoint_name
the name of the endpointdata::DataFrame
data used for the studydesign::NamedTuple
number of subjects in each sequencemodel
statistical models used for the analysismodel_stats
statistics for the modelstat_tests
p-valuesresult::DataFrame
results for inference in a Dataframe formatresult_table::OrderedDict{Symbol,Any}
results in an OrderedDict formatinput_parameters
a copy of the input parameters used
Examples
julia> data = dataset(joinpath("bioequivalence", "RST_RTS_SRT_STR_TRS_TSR", "PJ2017_4_5"))
186×5 DataFrame
Row │ id sequence period AUC Cmax
│ Int64 String3 Int64 Int64? Int64?
─────┼───────────────────────────────────────────
1 │ 1 SRT 1 7260 1633
2 │ 1 SRT 2 6463 1366
3 │ 1 SRT 3 8759 2141
4 │ 2 RTS 1 3457 776
5 │ 2 RTS 2 6556 2387
6 │ 2 RTS 3 4081 1355
7 │ 4 TSR 1 4006 1326
8 │ 4 TSR 2 4879 1028
9 │ 4 TSR 3 3817 1052
10 │ 5 STR 1 4250 945
11 │ 5 STR 2 3487 1041
⋮ │ ⋮ ⋮ ⋮ ⋮ ⋮
177 │ 61 RTS 3 3779 1144
178 │ 62 SRT 1 5787 1461
179 │ 62 SRT 2 7069 1995
180 │ 62 SRT 3 6530 1236
181 │ 63 TRS 1 2204 495
182 │ 63 TRS 2 2927 770
183 │ 63 TRS 3 missing missing
184 │ 67 RST 1 4045 1025
185 │ 67 RST 2 7865 2668
186 │ 67 RST 3 missing missing
165 rows omitted
julia> output = pumas_be(data, endpoint = :Cmax)
sequence ╲ period │ 1 2 3
──────────────────┼───────────
RST │ 9 9 8
RTS │ 11 11 11
SRT │ 11 11 11
STR │ 10 10 10
TRS │ 11 11 10
TSR │ 10 10 10
-----------------------------------------------------------------------------------------
Paradigm: 3 formulations
Model: Linear model
Criteria: Standard ABE
Endpoint: Cmax
Formulations: Reference(R), Test(S and T)
-----------------------------------------------------------------------------------------
Results(Cmax) Assessment Criteria
-----------------------------------------------------------------------------------------
S Geometric Mean S/R Ratio (%) 159.4
Degrees of Freedom 118
90% Confidence Interval (%) [146.1, 173.9] Fail CI ⊆ [80, 125]
-----------------------------------------------------------------------------------------
T Geometric Mean T/R Ratio (%) 129.9
Degrees of Freedom 118
90% Confidence Interval (%) [119.1, 141.8] Fail CI ⊆ [80, 125]
-----------------------------------------------------------------------------------------
Variability CV (%) | σ̂ 29.69 | 0.2907
-----------------------------------------------------------------------------------------
julia> output.model
StatsModels.TableRegressionModel{GLM.LinearModel{GLM.LmResp{Vector{Float64}}, GLM.DensePredChol{Float64, LinearAlgebra.CholeskyPivoted{Float64, Matrix{Float64}, Vector{Int64}}}}, Matrix{Float64}}
endpoint ~ 1 + sequence + formulation + period + sequence & id_within_sequence
Coefficients:
──────────────────────────────────────────────────────────────────────────────────────────────────────────────
Coef. Std. Error t Pr(>|t|) Lower 95% Upper 95%
──────────────────────────────────────────────────────────────────────────────────────────────────────────────
(Intercept) 6.62478 0.0712859 92.93 <1e-99 6.48361 6.76595
sequence: RTS 0.063206 0.0766071 0.83 0.4110 -0.0884968 0.214909
sequence: SRT 0.154313 0.0766071 2.01 0.0462 0.00260986 0.306016
sequence: STR -0.157545 0.0782601 -2.01 0.0464 -0.312522 -0.00256894
sequence: TRS 0.139309 0.0773718 1.80 0.0743 -0.0139084 0.292526
sequence: TSR 0.0515892 0.0782601 0.66 0.5111 -0.103387 0.206566
formulation: S 0.466225 0.0525563 8.87 <1e-14 0.362149 0.570301
formulation: T 0.261828 0.0525354 4.98 <1e-05 0.157794 0.365862
period: 2 0.108264 0.0522307 2.07 0.0404 0.00483251 0.211695
period: 3 0.065041 0.0528643 1.23 0.2210 -0.0396448 0.169727
sequence: RST & id_within_sequence: 2 -0.3262 0.15878 -2.05 0.0421 -0.640626 -0.0117729
sequence: RTS & id_within_sequence: 2 0.331286 0.16 2.07 0.0406 0.0144416 0.64813
sequence: SRT & id_within_sequence: 2 -0.501131 0.16 -3.13 0.0022 -0.817975 -0.184287
sequence: STR & id_within_sequence: 2 0.0716688 0.159198 0.45 0.6534 -0.243587 0.386925
sequence: TRS & id_within_sequence: 2 0.301479 0.160375 1.88 0.0626 -0.0161081 0.619065
sequence: TSR & id_within_sequence: 2 0.102741 0.159198 0.65 0.5199 -0.212515 0.417997
sequence: RST & id_within_sequence: 3 -0.51875 0.15878 -3.27 0.0014 -0.833177 -0.204324
sequence: RTS & id_within_sequence: 3 0.0552092 0.16 0.35 0.7307 -0.261635 0.372053
sequence: SRT & id_within_sequence: 3 -0.507347 0.16 -3.17 0.0019 -0.824191 -0.190502
sequence: STR & id_within_sequence: 3 0.170922 0.159198 1.07 0.2852 -0.144334 0.486178
sequence: TRS & id_within_sequence: 3 0.433913 0.160375 2.71 0.0078 0.116326 0.7515
sequence: TSR & id_within_sequence: 3 0.28292 0.159198 1.78 0.0781 -0.0323359 0.598176
sequence: RST & id_within_sequence: 4 -0.223057 0.15878 -1.40 0.1627 -0.537483 0.0913701
sequence: RTS & id_within_sequence: 4 0.733329 0.16 4.58 <1e-04 0.416485 1.05017
sequence: SRT & id_within_sequence: 4 -0.271254 0.16 -1.70 0.0926 -0.588098 0.0455901
sequence: STR & id_within_sequence: 4 -0.314543 0.159198 -1.98 0.0505 -0.629799 0.00071311
sequence: TRS & id_within_sequence: 4 -0.0758404 0.160375 -0.47 0.6372 -0.393427 0.241746
sequence: TSR & id_within_sequence: 4 -0.696306 0.159198 -4.37 <1e-04 -1.01156 -0.38105
sequence: RST & id_within_sequence: 5 0.0929178 0.15878 0.59 0.5595 -0.221509 0.407344
sequence: RTS & id_within_sequence: 5 -0.396815 0.16 -2.48 0.0145 -0.713659 -0.0799707
sequence: SRT & id_within_sequence: 5 0.590422 0.16 3.69 0.0003 0.273578 0.907266
sequence: STR & id_within_sequence: 5 -0.358415 0.159198 -2.25 0.0262 -0.673671 -0.0431591
sequence: TRS & id_within_sequence: 5 0.275196 0.160375 1.72 0.0888 -0.0423908 0.592783
sequence: TSR & id_within_sequence: 5 -0.31622 0.159198 -1.99 0.0493 -0.631476 -0.000964371
sequence: RST & id_within_sequence: 6 -0.33796 0.15878 -2.13 0.0354 -0.652387 -0.0235336
sequence: RTS & id_within_sequence: 6 0.0150445 0.16 0.09 0.9252 -0.3018 0.331889
sequence: SRT & id_within_sequence: 6 -0.150983 0.16 -0.94 0.3473 -0.467827 0.165862
sequence: STR & id_within_sequence: 6 -0.155991 0.159198 -0.98 0.3292 -0.471246 0.159265
sequence: TRS & id_within_sequence: 6 -0.043903 0.160375 -0.27 0.7848 -0.36149 0.273684
sequence: TSR & id_within_sequence: 6 0.604415 0.159198 3.80 0.0002 0.289159 0.919671
sequence: RST & id_within_sequence: 7 -0.0104784 0.15878 -0.07 0.9475 -0.324905 0.303948
sequence: RTS & id_within_sequence: 7 -0.73212 0.16 -4.58 <1e-04 -1.04896 -0.415276
sequence: SRT & id_within_sequence: 7 0.431845 0.16 2.70 0.0080 0.115001 0.748689
sequence: STR & id_within_sequence: 7 -0.0893864 0.159198 -0.56 0.5755 -0.404642 0.22587
sequence: TRS & id_within_sequence: 7 0.0591428 0.160375 0.37 0.7130 -0.258444 0.376729
sequence: TSR & id_within_sequence: 7 -0.93299 0.159198 -5.86 <1e-07 -1.24825 -0.617734
sequence: RST & id_within_sequence: 8 0.558771 0.15878 3.52 0.0006 0.244345 0.873198
sequence: RTS & id_within_sequence: 8 -0.1594 0.16 -1.00 0.3212 -0.476244 0.157444
sequence: SRT & id_within_sequence: 8 -0.316077 0.16 -1.98 0.0505 -0.632921 0.000767652
sequence: STR & id_within_sequence: 8 0.377635 0.159198 2.37 0.0193 0.0623787 0.692891
sequence: TRS & id_within_sequence: 8 -0.500216 0.160375 -3.12 0.0023 -0.817802 -0.182629
sequence: TSR & id_within_sequence: 8 0.246161 0.159198 1.55 0.1247 -0.0690946 0.561417
sequence: RST & id_within_sequence: 9 0.498742 0.191139 2.61 0.0102 0.120235 0.87725
sequence: RTS & id_within_sequence: 9 -0.0536409 0.16 -0.34 0.7380 -0.370485 0.263203
sequence: SRT & id_within_sequence: 9 0.173038 0.16 1.08 0.2817 -0.143807 0.489882
sequence: STR & id_within_sequence: 9 -0.330719 0.159198 -2.08 0.0399 -0.645975 -0.0154627
sequence: TRS & id_within_sequence: 9 0.409442 0.160375 2.55 0.0120 0.0918552 0.727029
sequence: TSR & id_within_sequence: 9 0.386147 0.159198 2.43 0.0168 0.0708915 0.701403
sequence: RST & id_within_sequence: 10 0.0 NaN NaN NaN NaN NaN
sequence: RTS & id_within_sequence: 10 0.262141 0.16 1.64 0.1040 -0.0547029 0.578985
sequence: SRT & id_within_sequence: 10 -0.0533425 0.16 -0.33 0.7394 -0.370187 0.263502
sequence: STR & id_within_sequence: 10 0.573641 0.159198 3.60 0.0005 0.258385 0.888897
sequence: TRS & id_within_sequence: 10 -0.343073 0.160375 -2.14 0.0345 -0.66066 -0.0254862
sequence: TSR & id_within_sequence: 10 0.272039 0.159198 1.71 0.0901 -0.0432167 0.587295
sequence: RST & id_within_sequence: 11 0.0 NaN NaN NaN NaN NaN
sequence: RTS & id_within_sequence: 11 -0.281096 0.16 -1.76 0.0815 -0.59794 0.035748
sequence: SRT & id_within_sequence: 11 0.255426 0.16 1.60 0.1131 -0.0614185 0.57227
sequence: STR & id_within_sequence: 11 0.0 NaN NaN NaN NaN NaN
sequence: TRS & id_within_sequence: 11 -0.52366 0.19394 -2.70 0.0080 -0.907714 -0.139606
sequence: TSR & id_within_sequence: 11 0.0 NaN NaN NaN NaN NaN
──────────────────────────────────────────────────────────────────────────────────────────────────────────────
Bioequivalence.GeometricMeanRatioBounds
— TypeGeometricMeanRatioBounds(lower_bound::Real = 0.8, upper_bound::Real = 1.25)
Criteria for the point estimate. Checks that the geometric mean ratio (GMR) lies within the accepted range.
Bioequivalence.ReferenceScaledAverageBioequivalance
— TypeReferenceScaledAverageBioequivalance(
data::AbstractDataFrame,
𝜃::Real,
σwᵣ::Real = -1;
k::Union{Real, Missing} = -1,
level::Real = 0.9,
level_y::Real = 0.95,
userepeatedobsonly::Bool = true
) -> ReferenceScaledAverageBioequivalance
Reference-scaled average bioequivalence.
Arguments
data::AbstractDataFrame
: dataset adhering to the schema frompreprocess_be
.𝜃::Real
: parameter for reference-scaling.σwᵣ::Real
: estimate for the within-subject variability. If negative, the function will compute it.k::Real
: degrees of freedom of the within-subject variability. If negative, the function will compute it.level::Real
: confidence level for the confidence interval.level_y::Real
: confidence level for the upper bound of (Ȳₜ - Ȳᵣ)² - 𝜃 * σwᵣ².userepeatedobsonly
: controls the behavior ofwithin_subject_variability
if used to estimateσwᵣ
andk
.
See also preprocess_be
and within_subject_variability
Reference
Food and Drug Administration (2021). Bioequivalence Studies With Pharmacokinetic Endpoints for Drugs Submitted Under an ANDA Guidance for Industry. https://www.fda.gov/media/87219/download.
Examples
julia> data = dataset(joinpath("bioequivalence", "RTTR_TRRT", "SLTGSF2020_DS16"));
julia> pkdata = preprocess_be(data, endpoint = :PK);
julia> rsabe = ReferenceScaledAverageBioequivalance(pkdata, 0.76)
Critical boundary: -0.0416
Regulatory parameter: 0.76
95.0% upper confidence bound with 36.0 degrees of freedom
Bioequivalence.WithinSubjectVariabilityRatio
— TypeWithinSubjectVariabilityRatio(upper_bound::Real = 2.5)
Requirement for the upper limit of the 90% equal-tails confidence interval for within-subject variability test/reference ratio is less than or equal to the upper limit.
Bioequivalence.assess_be
— Functionassess_be(
criterion::BioequivalenceCriterion,
endpoint_output::BioequivalenceEndpointOutput
) -> BioequivalenceEndpointDecision
assess_be(
criteria::AbstractVector{<:BioequivalenceCriterion},
endpoint_output::BioequivalenceEndpointOutput
) -> BioequivalenceEndpointDecision
Return a BioequivalenceEndpointDecision
struct which includes properties crtieria
for a vector of criterion. The result of the assessment is accessible through the assessments
property which is a BitMatrix. The rows refer to a formulation comparison (e.g., R|T) and the columns whether the criterion was passed or not.
Bioequivalence.assess_be
— Methodassess_be(criteria::AbstractVector{<:BioequivalenceCriterion}, endpoint_output::BioequivalenceEndpointOutput)
Return the average bioequivalence conclusions based on the specified criteria.
Examples
julia> data = dataset(joinpath("bioequivalence", "RTTR_TRRT", "SLTGSF2020_DS16"))
152×4 DataFrame
Row │ id sequence period PK
│ Int64 String7 Int64 Float64
─────┼──────────────────────────────────
1 │ 1 RTTR 1 0.2813
2 │ 1 RTTR 2 0.2947
3 │ 1 RTTR 3 0.5471
4 │ 1 RTTR 4 0.651
5 │ 2 RTTR 1 0.2024
6 │ 2 RTTR 2 0.1782
7 │ 2 RTTR 3 0.2076
8 │ 2 RTTR 4 0.3604
9 │ 3 TRRT 1 0.4332
10 │ 3 TRRT 2 0.3131
11 │ 3 TRRT 3 0.2132
⋮ │ ⋮ ⋮ ⋮ ⋮
143 │ 38 RTTR 3 2.6522
144 │ 38 RTTR 4 1.2808
145 │ 39 RTTR 1 0.3847
146 │ 39 RTTR 2 0.2991
147 │ 39 RTTR 3 0.3353
148 │ 39 RTTR 4 0.3483
149 │ 40 RTTR 1 1.0289
150 │ 40 RTTR 2 0.753
151 │ 40 RTTR 3 0.7894
152 │ 40 RTTR 4 0.6129
131 rows omitted
julia> output = pumas_be(data, endpoint = :PK)
sequence ╲ period │ 1 2 3 4
──────────────────┼───────────────
RTTR │ 20 20 20 20
TRRT │ 18 18 18 18
-----------------------------------------------------------------------------------------
Paradigm: Replicated crossover that supports reference scaling
Model: Mixed model (unequal variance)
Criteria: Standard ABE
Endpoint: PK
Formulations: Reference(R), Test(T)
-----------------------------------------------------------------------------------------
Results(PK) Assessment Criteria
-----------------------------------------------------------------------------------------
T Geometric Mean T/R Ratio (%) 78.83
Degrees of Freedom 86.57
90% Confidence Interval (%) [69.31, 89.66] Fail CI ⊆ [80, 125]
-----------------------------------------------------------------------------------------
Variability CVᵣ (%) | σ̂ᵣ 49.72 | 0.47
CVₜ (%) | σ̂ₜ 51.41 | 0.4843
Variability Ratio (%) 103.1
-----------------------------------------------------------------------------------------
ANOVA Treatment (p-value) 0.00283
Sequence (p-value) 0.5266
Period (p-value) 0.03876
-----------------------------------------------------------------------------------------
julia> assess_be(StandardBioequivalenceCriterion, output)
Formulation: T - R -- Fail
LB ≥ 0.8% ^ UB ≤ 1.25% -- Fail
julia> assess_be(FDA, output)
Formulation: T - R -- Fail
0.8 ≤ GMR ≤ 1.25 -- Fail
Reference Scaled Average Bioequivalance w/ 𝜃: 0.796689, CV_min: 0.3, CV_max: Inf -- Pass
julia> assess_be(FDA_NarrowTherapeuticIndex, output)
Formulation: T - R -- Fail
LB ≥ 0.8% ^ UB ≤ 1.25% -- Fail
Reference Scaled Average Bioequivalance w/ 𝜃: 1.110084, CV_min: 0.0, CV_max: 0.2142 -- Fail
Upper bound of the within-subject variability ratio ≤ 2.5 -- Pass
Bioequivalence.detect_design
— Functiondetect_design(sequences::AbstractVector) ->
NamedTuple{(:design, :replicated, :crossover), Tuple{String, ReplicationType, Bool}}
detect_design(
data::AbstractDataFrame,
sequence::Union{AbstractString, Symbol} = :sequence
) -> NamedTuple{(:design, :replicated, :supports_rsabe, :crossover), Tuple{String, ReplicationType, Bool, Bool}}
Return a named tuple which describes the design. The fields are:
- :design - a String describing the design.
- :replicated - a value of ReplicationType.
- :supports_rsabe - true if RSABE is supported with this design.
- :crossover - true if a crossover design.
Bioequivalence.generate_design
— Methodgenerate_design(
sequences::AbstractVector{<:AbstractString},
amt::Union{Number,AbstractVector{<:Number}},
subjects_per_sequence::Union{<:Integer,AbstractVector{<:Integer}},
) -> DataFrame
Returns a DataFrame with id, sequence, period, amt, evid, cmt, and time. It can be used to quickly set up data for Pumas, NCA, and Bioequivalence. In order to add covariates, use innerjoin
to join the result of this function with another DataFrame with covariates.
Examples
julia> skeleton = generate_design(["RT", "TR"], [0, 50], 10)
40×8 DataFrame
Row │ id sequence period formulation amt time evid cmt
│ Int64 Cat… Int64 Char Int64 Int64 Int64 Int64
─────┼──────────────────────────────────────────────────────────────────
1 │ 1 RT 1 R 0 0 4 1
2 │ 1 RT 2 T 50 0 4 1
3 │ 2 RT 1 R 0 0 4 1
4 │ 2 RT 2 T 50 0 4 1
5 │ 3 RT 1 R 0 0 4 1
6 │ 3 RT 2 T 50 0 4 1
7 │ 4 RT 1 R 0 0 4 1
8 │ 4 RT 2 T 50 0 4 1
9 │ 5 RT 1 R 0 0 4 1
10 │ 5 RT 2 T 50 0 4 1
11 │ 6 RT 1 R 0 0 4 1
⋮ │ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮
31 │ 16 TR 1 T 50 0 4 1
32 │ 16 TR 2 R 0 0 4 1
33 │ 17 TR 1 T 50 0 4 1
34 │ 17 TR 2 R 0 0 4 1
35 │ 18 TR 1 T 50 0 4 1
36 │ 18 TR 2 R 0 0 4 1
37 │ 19 TR 1 T 50 0 4 1
38 │ 19 TR 2 R 0 0 4 1
39 │ 20 TR 1 T 50 0 4 1
40 │ 20 TR 2 R 0 0 4 1
19 rows omitted
julia> skeleton = generate_design(["RTRT", "TRTR"], [50, 75], [12, 10])
88×8 DataFrame
Row │ id sequence period formulation amt time evid cmt
│ Int64 Cat… Int64 Char Int64 Int64 Int64 Int64
─────┼──────────────────────────────────────────────────────────────────
1 │ 1 RTRT 1 R 50 0 4 1
2 │ 1 RTRT 2 T 75 0 4 1
3 │ 1 RTRT 3 R 50 0 4 1
4 │ 1 RTRT 4 T 75 0 4 1
5 │ 2 RTRT 1 R 50 0 4 1
6 │ 2 RTRT 2 T 75 0 4 1
7 │ 2 RTRT 3 R 50 0 4 1
8 │ 2 RTRT 4 T 75 0 4 1
9 │ 3 RTRT 1 R 50 0 4 1
10 │ 3 RTRT 2 T 75 0 4 1
11 │ 3 RTRT 3 R 50 0 4 1
⋮ │ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮
79 │ 20 TRTR 3 T 75 0 4 1
80 │ 20 TRTR 4 R 50 0 4 1
81 │ 21 TRTR 1 T 75 0 4 1
82 │ 21 TRTR 2 R 50 0 4 1
83 │ 21 TRTR 3 T 75 0 4 1
84 │ 21 TRTR 4 R 50 0 4 1
85 │ 22 TRTR 1 T 75 0 4 1
86 │ 22 TRTR 2 R 50 0 4 1
87 │ 22 TRTR 3 T 75 0 4 1
88 │ 22 TRTR 4 R 50 0 4 1
67 rows omitted
Bioequivalence.geocv2sigma
— Methodgeocv2sigma(CV::Union{Real,Missing}) = √(log(1 + CV^2))
Transform the the coefficient of variation (CV) to the σ parameter of a log-normal distribution.
Examples
julia> geocv2sigma(0.30)
0.29356037920852396
Bioequivalence.implied_design
— Methodimplied_design(data::AbstractDataFrame) -> NamedTuple
Sequence and number of subjects per sequence
Bioequivalence.inference_model_type
— Methodinference_model_type(be_output::BioequivalenceEndpointOutput)::InferenceModelType
Determines the inference model type used in a bioequivalence study for an endpoint.
Bioequivalence.is_preprocessed
— Methodis_preprocessed(data::AbstractDataFrame)
Returns true
if data
is suspected of having the form returned by preprocess_be
.
Bioequivalence.legacy_show
— Methodlegacy_show(obj::BioequivalenceEndpointOutput)
This can be used to present output of pumas_be
in legacy mode, presenting a dataframe obj.result
in place of tabular output (out.result_table
).
Examples
julia> data = dataset(joinpath("bioequivalence", "RTTR_TRRT", "PJ2017_4_3"));
julia> legacy_show(pumas_be(data))
sequence ╲ period │ 1 2 3 4
──────────────────┼───────────
RTTR │ 8 8 8 8
TRRT │ 9 9 9 8
Reference scaled using 𝜃 = 0.797
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
δ SE lnLB lnUB GMR LB UB CVᵣ CVₜ σ_ratio σ⁺ cb dof
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
T - R 0.03568 0.02431 -0.006884 0.07826 1.036 0.9931 1.082 0.08022 0.1084 1.35 2.118 0.001813 15.25
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Bioequivalence.preprocess_be
— Methodpreprocess_be(
data::AbstractDataFrame,
id::Union{AbstractString, Symbol} = :id,
sequence::Union{AbstractString, Symbol} = :sequence,
period::Union{AbstractString, Symbol} = :period,
endpoint::Union{AbstractString, Symbol} = :AUC,
logtransformed::Bool = false
) -> DataFrame
Return the standardized dataset with id
, sequence
, period
, formulation
, and endpoint
. The standardized dataset:
- selects only relevant variables
- applies the natural log transformation to the endpoint if in natural scale
- renames variables to their canonical name for the functions
- drops missing observations
- computes the formulation based on the sequence and period variables
- converts the variables into the appropiate format for analysis (e.g., factors)
The sequence/formulation take values RT, RST, or ABCD based on alphabetical order and number of formulations.
Examples
julia> data = dataset(joinpath("bioequivalence", "RT_TR", "SLF2014_1"))
36×4 DataFrame
Row │ id sequence period AUC
│ Int64 String3 Int64 Float64
─────┼──────────────────────────────────
1 │ 1 RT 1 181.09
2 │ 1 RT 2 210.14
3 │ 2 RT 1 114.48
4 │ 2 RT 2 98.72
5 │ 3 TR 1 225.95
6 │ 3 TR 2 241.09
7 │ 4 RT 1 176.91
8 │ 4 RT 2 186.65
9 │ 5 TR 1 147.01
10 │ 5 TR 2 139.56
11 │ 6 TR 1 97.53
⋮ │ ⋮ ⋮ ⋮ ⋮
27 │ 14 TR 1 179.96
28 │ 14 TR 2 181.09
29 │ 15 TR 1 173.86
30 │ 15 TR 2 206.66
31 │ 16 RT 1 144.0
32 │ 16 RT 2 143.25
33 │ 17 RT 1 185.1
34 │ 17 RT 2 192.22
35 │ 18 TR 1 117.99
36 │ 18 TR 2 125.5
15 rows omitted
julia> preprocess_be(data)
36×6 DataFrame
Row │ id id_within_sequence sequence period formulation endpoint
│ Cat… Cat… Cat… Cat… Cat… Float64
─────┼───────────────────────────────────────────────────────────────────
1 │ 1 1 RT 1 R 5.19899
2 │ 1 1 RT 2 T 5.34777
3 │ 2 2 RT 1 R 4.7404
4 │ 2 2 RT 2 T 4.59229
5 │ 3 1 TR 1 T 5.42031
6 │ 3 1 TR 2 R 5.48517
7 │ 4 3 RT 1 R 5.17564
8 │ 4 3 RT 2 T 5.22924
9 │ 5 2 TR 1 T 4.9905
10 │ 5 2 TR 2 R 4.93849
11 │ 6 3 TR 1 T 4.58016
⋮ │ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮
27 │ 14 7 TR 1 T 5.19273
28 │ 14 7 TR 2 R 5.19899
29 │ 15 8 TR 1 T 5.15825
30 │ 15 8 TR 2 R 5.33107
31 │ 16 8 RT 1 R 4.96981
32 │ 16 8 RT 2 T 4.96459
33 │ 17 9 RT 1 R 5.2209
34 │ 17 9 RT 2 T 5.25864
35 │ 18 9 TR 1 T 4.7706
36 │ 18 9 TR 2 R 4.83231
15 rows omitted
Bioequivalence.pumas_be
— Functionpumas_be(
data::AbstractDataFrame,
criteria::AbstractVector{<:BioequivalenceCriterion} = StandardBioequivalenceCriterion;
endpoint::Union{AbstractString,Symbol} = "AUC",
logtransformed::Bool = false,
reference_scale::Union{Real,Nothing} = nothing,
cv_max::Real = Inf,
id::Union{AbstractString,Symbol} = "id",
sequence::Union{AbstractString,Symbol} = "sequence",
period::Union{AbstractString,Symbol} = "period",
nonparametric::Bool = occursin(r"(?i)tmax", string(endpoint)),
homogeneity::Union{Bool, Nothing} = nothing,
userepeatedobsonly::Bool = true,
reml::Bool = true,
level::Real = 0.9,
alpha::Real = 0.1,
level_y::Real = 0.95,
sigdigits::Integer = 4,
) -> BioequivalenceEndpointOutput
BioequivalenceEndpointOutput
constructor. See also: BioequivalenceEndpointOutput
, preprocess_be
, and run_be
.
Arguments
data
: must haveid
,sequence
,period
, and anendpoint
.criteria
: by default this argument can be left blank. Yet if it specified,assess_be
will use a different assessment. UseNoAssessmentBioequivalenceCriterion
if wishing not to assess.endpoint
: which variable is the endpoint?logtransformed
: has the endpoint been log transformed?id
: which variable is the subject identifier?sequence
: which variable is the sequence?period
: which variable is the period?nonparametric
: whether to use a nonparametric (default if endpoint includestmax
ignoring case) or parametric model.homogeneity
: whether formulation groups should be modeled with equal varianceuserepeatedobsonly
: whether estimating the within subject variability should only repeated observationsreference_scale
: 𝜃 for reference scale (e.g., FDA ≈ 0.797, FDA/NTI ≈ 1.11, EMA = 0.76). If nothing (default) then values set based on criteria.cv_max
: maximum within subject variability for reference scaling (FDA = Inf, FDA/NTI = 0.2142, EMA = 0.5). Ifreference_scale
is nothing then value adjusted based on criteria.reml
: whether the linear mixed model should use restricted maximum likelihood or maximum likelihoodlevel
: applies to the confidence intervals for the GMRalpha
: applies to the upper bound of the within subject variability ratiolevel_y
: applies to the critical boundary for reference-scaled average bioequivalencesigdigits
: results given with how many significant digits.
Current designs include: nonparametric, parallel, and various crossover designs | Description | Treatments | Periods | Sequences | Replicated | Crossover | |–––––––––––––-|––––––|––––-|–––––-|––––––|–––––-| | R_T
| 2 | 1 | 2 | No | No | | RT_TR
| 2 | 2 | 2 | No | Yes | | RR_RT_TR_TT
| 2 | 2 | 4 | No | Yes | | RTR_TRT
| 2 | 3 | 2 | Fully | Yes | | RTR_TRR
| 2 | 3 | 2 | Partially | Yes | | RTT_TRR
| 2 | 3 | 2 | Fully | Yes | | RRT_RTR_TRR
| 2 | 3 | 3 | Partially | Yes | | RTRT_TRTR
| 2 | 4 | 2 | Fully | Yes | | RRTT_TTRR
| 2 | 4 | 2 | Fully | Yes | | RTTR_TRRT
| 2 | 4 | 2 | Fully | Yes | | RRTT_RTTR_TRRT_TTRR
| 2 | 4 | 4 | Fully | Yes | | RTRT_RTTR_TRRT_TRTR
| 2 | 4 | 4 | Fully | Yes | | RR_TT
| 2 | >1 | 2 | Fully | No | | RST_RTS_SRT_STR_TRS_TSR
| 3 | 3 | 6 | No | Yes | | ADBC_BACD_CBDA_DCAB
| 4 | 4 | 4 | No | Yes |
Examples
julia> data = dataset(joinpath("bioequivalence", "RT_TR", "SLF2014_1"))
36×4 DataFrame
Row │ id sequence period AUC
│ Int64 String3 Int64 Float64
─────┼──────────────────────────────────
1 │ 1 RT 1 181.09
2 │ 1 RT 2 210.14
3 │ 2 RT 1 114.48
4 │ 2 RT 2 98.72
5 │ 3 TR 1 225.95
6 │ 3 TR 2 241.09
7 │ 4 RT 1 176.91
8 │ 4 RT 2 186.65
9 │ 5 TR 1 147.01
10 │ 5 TR 2 139.56
11 │ 6 TR 1 97.53
⋮ │ ⋮ ⋮ ⋮ ⋮
27 │ 14 TR 1 179.96
28 │ 14 TR 2 181.09
29 │ 15 TR 1 173.86
30 │ 15 TR 2 206.66
31 │ 16 RT 1 144.0
32 │ 16 RT 2 143.25
33 │ 17 RT 1 185.1
34 │ 17 RT 2 192.22
35 │ 18 TR 1 117.99
36 │ 18 TR 2 125.5
15 rows omitted
julia> output = pumas_be(data)
sequence ╲ period │ 1 2
──────────────────┼─────
RT │ 9 9
TR │ 9 9
-----------------------------------------------------------------------------------------
Paradigm: Non replicated crossover design
Model: Linear model
Criteria: Standard ABE
Endpoint: AUC
Formulations: Reference(R), Test(T)
-----------------------------------------------------------------------------------------
Results(AUC) Assessment Criteria
-----------------------------------------------------------------------------------------
T Geometric Mean T/R Ratio (%) 95.09
Degrees of Freedom 16
90% Confidence Interval (%) [90.76, 99.62] Pass CI ⊆ [80, 125]
-----------------------------------------------------------------------------------------
Variability CV (%) | σ̂ 8.01 | 0.08
-----------------------------------------------------------------------------------------
ANOVA Treatment (p-value) 0.077
Sequence (p-value) 2.0e-5
Period (p-value) 0.01702
-----------------------------------------------------------------------------------------
julia> output = pumas_be(data, nonparametric = true)
sequence ╲ period │ 1 2
──────────────────┼─────
RT │ 9 9
TR │ 9 9
-----------------------------------------------------------------------------
Paradigm: Nonparametric analysis
Model: Signed rank test
Criteria: Standard ABE
Endpoint: AUC
Formulations: Reference(R), Test(T)
-----------------------------------------------------------------------------
Results(AUC) Assessment Criteria
-----------------------------------------------------------------------------
T 90% Confidence Interval (%) [89.9, 99.88] Pass CI ⊆ [80, 125]
-----------------------------------------------------------------------------
julia> data = dataset(joinpath("bioequivalence", "RTT_TRR", "PJ2017_4_1"))
285×5 DataFrame
Row │ id sequence period AUC Cmax
│ Int64 String3 Int64 Float64? Float64?
─────┼─────────────────────────────────────────────
1 │ 101 TRR 1 12.26 0.511
2 │ 101 TRR 2 16.19 0.688
3 │ 101 TRR 3 11.34 0.533
4 │ 102 TRR 1 397.98 13.27
5 │ 102 TRR 2 267.63 7.933
6 │ 102 TRR 3 487.55 12.952
7 │ 103 TRR 1 243.81 16.771
8 │ 103 TRR 2 141.7 6.926
9 │ 103 TRR 3 198.44 9.257
10 │ 109 TRR 1 182.52 8.816
11 │ 109 TRR 2 112.34 4.921
⋮ │ ⋮ ⋮ ⋮ ⋮ ⋮
276 │ 186 RTT 3 87.63 4.87
277 │ 190 RTT 1 82.78 3.88
278 │ 190 RTT 2 164.56 7.37
279 │ 190 RTT 3 213.98 7.01
280 │ 191 RTT 1 98.86 4.59
281 │ 191 RTT 2 99.02 2.96
282 │ 191 RTT 3 75.48 2.38
283 │ 194 RTT 1 21.29 1.51
284 │ 194 RTT 2 46.3 2.74
285 │ 194 RTT 3 15.41 1.41
264 rows omitted
julia> output = pumas_be(data)
sequence ╲ period │ 1 2 3
──────────────────┼───────────
RTT │ 46 45 43
TRR │ 47 47 47
-----------------------------------------------------------------------------------------
Paradigm: Replicated crossover that does not support reference scaling
Model: Mixed model (unequal variance)
Criteria: Standard ABE
Endpoint: AUC
Formulations: Reference(R), Test(T)
-----------------------------------------------------------------------------------------
Results(AUC) Assessment Criteria
-----------------------------------------------------------------------------------------
T Geometric Mean T/R Ratio (%) 97.38
Degrees of Freedom 148.7
90% Confidence Interval (%) [86.86, 109.2] Pass CI ⊆ [80, 125]
-----------------------------------------------------------------------------------------
Variability CVᵣ (%) | σ̂ᵣ 42.75 | 0.4097
CVₜ (%) | σ̂ₜ 69.65 | 0.6289
-----------------------------------------------------------------------------------------
ANOVA Treatment (p-value) 0.7013
Sequence (p-value) 0.2506
Period (p-value) 0.01209
-----------------------------------------------------------------------------------------
Bioequivalence.reference_scaled_acceptance_bounds
— Functionreference_scaled_acceptance_bounds(σwr::Real, θ::Real)
reference_scaled_acceptance_bounds(obj::BioequivalenceEndpointOutput)
Return the lower and upper bounds based on the reference within subject variability and regulatory parameter.
Reference: European Medicines Agency (2010). "GUIDELINE ON THE INVESTIGATION OF BIOEQUIVALENCE": 4.1.10 Highly variable drugs or drug products. Doc. Ref.: CPMP/EWP/QWP/1401/98 Rev. 1/ Corr **
Examples
julia> data = dataset(joinpath("bioequivalence", "RTTR_TRRT", "PJ2017_4_3"));
julia> output = pumas_be(data)
sequence ╲ period │ 1 2 3 4
──────────────────┼───────────
RTTR │ 8 8 8 8
TRRT │ 9 9 9 8
-----------------------------------------------------------------------------------------
Paradigm: Replicated crossover that supports reference scaling
Model: Mixed model (unequal variance)
Criteria: Standard ABE
Endpoint: AUC
Formulations: Reference(R), Test(T)
-----------------------------------------------------------------------------------------
Results(AUC) Assessment Criteria
-----------------------------------------------------------------------------------------
T Geometric Mean T/R Ratio (%) 103.6
Degrees of Freedom 15.25
90% Confidence Interval (%) [99.31, 108.2] Pass CI ⊆ [80, 125]
-----------------------------------------------------------------------------------------
Variability CVᵣ (%) | σ̂ᵣ 8.02 | 0.0801
CVₜ (%) | σ̂ₜ 10.84 | 0.1081
Variability Ratio (%) 135
-----------------------------------------------------------------------------------------
ANOVA Treatment (p-value) 0.1624
Sequence (p-value) 0.3184
Period (p-value) 0.6651
-----------------------------------------------------------------------------------------
julia> reference_scaled_acceptance_bounds(output)
(0.9381852023891446, 1.0658876280007832)
julia> reference_scaled_acceptance_bounds(geocv2sigma(30), 0.76)
(0.13774539477808087, 7.259770837428591)
julia> reference_scaled_acceptance_bounds(geocv2sigma(21.42), (log(1 / 0.9) / 0.1)^2)
(0.06401589407631314, 15.62112057371101)
Bioequivalence.result_summary_table
— Methodresult_summary_table(endpoint_output::BioequivalenceEndpointOutput)
Creates a SummaryTables.Table
representing the endpoint output.
Bioequivalence.run_be
— Methodrun_be(
data::AbstractDataFrame;
reference_scale::Real = (log(1.25) / 0.25)^2,
cv_max::Real = Inf,
nonparametric::Bool = false,
homogeneity::Union{Bool, Nothing} = nothing,
userepeatedobsonly::Bool = true,
level::Real = 0.9,
alpha::Real = 0.1,
level_y::Real = 0.95,
reml::Bool = true,
sigdigits::Integer = 4,
) -> BioequivalenceEndpointOutput
BioequivalenceEndpointOutput
constructor.
See also: BioequivalenceEndpointOutput
.
Arguments
data
: must haveid
,sequence
,period
, and anendpoint
.nonparametric
: whether to use a nonparametric analysis (uncommon and usually reserved for Tmax)homogeneity
: whether formulation groups should be modeled with equal varianceuserepeatedobsonly
: whether estimating the within subject variability should only use repeated observationsreference_scale
: 𝜃 for reference scale (FDA ≈ 0.797, FDA/NTI ≈ 1.11, EMA = 0.76)cv_max
: maximum within subject variability for reference scaling (FDA = Inf, FDA/NTI = 0.2142, EMA = 0.5)reml
: whether the linear mixed model should use restricted maximum likelihood or maximum likelihood.level
: applies to the confidence intervals for the GMR.alpha
: applies to the upper bound of the within subject variability ratiolevel_y
: applies to the critical boundary for reference-scaled average bioequivalencesigdigits
: results given with how many significant digits.endpoint_name
the name of the endpoint
Current designs include: nonparametric, parallel, and various crossover designs
Description | Treatments | Periods | Sequences | Replicated | Crossover |
---|---|---|---|---|---|
R_T | 2 | 1 | 2 | No | No |
RT_TR | 2 | 2 | 2 | No | Yes |
RR_RT_TR_TT | 2 | 2 | 4 | No | Yes |
RTR_TRT | 2 | 3 | 2 | Fully | Yes |
RTR_TRR | 2 | 3 | 2 | Partially | Yes |
RTT_TRR | 2 | 3 | 2 | Fully | Yes |
RRT_RTR_TRR | 2 | 3 | 3 | Partially | Yes |
RTRT_TRTR | 2 | 4 | 2 | Fully | Yes |
RRTT_TTRR | 2 | 4 | 2 | Fully | Yes |
RTTR_TRRT | 2 | 4 | 2 | Fully | Yes |
RRTT_RTTR_TRRT_TTRR | 2 | 4 | 4 | Fully | Yes |
RTRT_RTTR_TRRT_TRTR | 2 | 4 | 4 | Fully | Yes |
RR_TT | 2 | >1 | 2 | Fully | No |
RST_RTS_SRT_STR_TRS_TSR | 3 | 3 | 6 | No | Yes |
ADBC_BACD_CBDA_DCAB | 4 | 4 | 4 | No | Yes |
Examples
julia> data = dataset(joinpath("bioequivalence", "RT_TR", "SLF2014_1"))
36×4 DataFrame
Row │ id sequence period AUC
│ Int64 String3 Int64 Float64
─────┼──────────────────────────────────
1 │ 1 RT 1 181.09
2 │ 1 RT 2 210.14
3 │ 2 RT 1 114.48
4 │ 2 RT 2 98.72
5 │ 3 TR 1 225.95
6 │ 3 TR 2 241.09
7 │ 4 RT 1 176.91
8 │ 4 RT 2 186.65
9 │ 5 TR 1 147.01
10 │ 5 TR 2 139.56
11 │ 6 TR 1 97.53
⋮ │ ⋮ ⋮ ⋮ ⋮
27 │ 14 TR 1 179.96
28 │ 14 TR 2 181.09
29 │ 15 TR 1 173.86
30 │ 15 TR 2 206.66
31 │ 16 RT 1 144.0
32 │ 16 RT 2 143.25
33 │ 17 RT 1 185.1
34 │ 17 RT 2 192.22
35 │ 18 TR 1 117.99
36 │ 18 TR 2 125.5
15 rows omitted
julia> pkdata = preprocess_be(data)
36×6 DataFrame
Row │ id id_within_sequence sequence period formulation endpoint
│ Cat… Cat… Cat… Cat… Cat… Float64
─────┼───────────────────────────────────────────────────────────────────
1 │ 1 1 RT 1 R 5.19899
2 │ 1 1 RT 2 T 5.34777
3 │ 2 2 RT 1 R 4.7404
4 │ 2 2 RT 2 T 4.59229
5 │ 3 1 TR 1 T 5.42031
6 │ 3 1 TR 2 R 5.48517
7 │ 4 3 RT 1 R 5.17564
8 │ 4 3 RT 2 T 5.22924
9 │ 5 2 TR 1 T 4.9905
10 │ 5 2 TR 2 R 4.93849
11 │ 6 3 TR 1 T 4.58016
⋮ │ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮
27 │ 14 7 TR 1 T 5.19273
28 │ 14 7 TR 2 R 5.19899
29 │ 15 8 TR 1 T 5.15825
30 │ 15 8 TR 2 R 5.33107
31 │ 16 8 RT 1 R 4.96981
32 │ 16 8 RT 2 T 4.96459
33 │ 17 9 RT 1 R 5.2209
34 │ 17 9 RT 2 T 5.25864
35 │ 18 9 TR 1 T 4.7706
36 │ 18 9 TR 2 R 4.83231
15 rows omitted
julia> output = run_be(pkdata)
sequence ╲ period │ 1 2
──────────────────┼─────
RT │ 9 9
TR │ 9 9
─────────────────────────────────────────────────────────────────────────────────────────────
δ SE lnLB lnUB GMR LB UB CV
─────────────────────────────────────────────────────────────────────────────────────────────
T - R -0.0503868 0.026658 -0.0969286 -0.00384499 0.950862 0.907621 0.996162 0.0801021
─────────────────────────────────────────────────────────────────────────────────────────────
Bioequivalence.sigma2geocv
— Methodsigma2geocv(σw::Union{Real,Missing}) = √(exp(σw^2) - 1)
Transform the σ parameter of a log-normal distribution to the coefficient of variation (CV).
Examples
julia> sigma2geocv(0.294)
0.3004689459216001
Bioequivalence.stat_tests_pvalues
— Methodstat_tests_pvalues(data::AbstractDataFrame)
Returns a named tuple of p values with p_formulation
, p_period
, p_subject_in_group
.
Bioequivalence.study_paradigm
— Methodstudy_paradigm(data::AbstractDataFrame, nonparametric::Bool)::EndpointStudyParadigm
Determines the study paradigm of a dataset.
Bioequivalence.study_paradigm
— Methodstudy_paradigm(be_output::BioequivalenceEndpointOutput)::EndpointStudyParadigm
Determines the study paradigm used in a bioequivalence study for an endpoint.
Bioequivalence.update_rsabe_theta!
— Methodupdate_rsabe_theta!(obj::ReferenceScaledAverageBioequivalance, 𝜃::Real) -> ReferenceScaledAverageBioequivalance
Modifies in-place the 𝜃 of the ReferenceScaledAverageBioequivalance and updates the associated critical boundary.
julia> data = dataset(joinpath("bioequivalence", "RTTR_TRRT", "SLTGSF2020_DS16"));
julia> pkdata = preprocess_be(data, endpoint = :PK);
julia> rsabe = ReferenceScaledAverageBioequivalance(pkdata, 0.76)
Critical boundary: -0.0416
Regulatory parameter: 0.76
95.0% upper confidence bound with 36.0 degrees of freedom
julia> update_rsabe_theta!(rsabe, 1.11)
Critical boundary: -0.1019
Regulatory parameter: 1.11
95.0% upper confidence bound with 36.0 degrees of freedom
Bioequivalence.within_subject_variability
— Methodwithin_subject_variability(
data::AbstractDataFrame;
userepeatedobsonly::Bool = true
allownonreplicated::Bool = false,
homogeneity::Union{Bool,Nothing} = nothing,
)
Return the within-subject variability estimate and degrees of freedom. It uses a linear model of the log-transformed PK response with fixed effects for subject ID and period. If userepeatedobsonly
, data used is a sample with only observations from repeated subject/treatment. If allownonreplicated
, the function returns a NamedTuple
of missing
s instead of throwing an error when the passed formulation is not replicated in any sequences. This option is only relevant for partially replicated designs.
The homogeneity
argument specifies if equal variances are assumed between formulations. When set to true
, multiple formulations are expected in data
. When set to false
, only a single formulation should be available in data
. In this case, design must be replicated. The default value of homogeneity
is false
for replicated designs and true
otherwise.
References:
Schütz H, Tomashevskiy M, Labes D, Shitova A, González-de la Parra M, Fuglsang A. 2020. Reference Datasets for Studies in a Replicate Design Intended for Average Bioequivalence with Expanding Limits. AAPS J. 22(2): Article 44. DOI: 10.1208/s12248-020-0427-6.
Examples
julia> data = dataset(joinpath("bioequivalence", "RTTR_TRRT", "PJ2017_4_3"));
julia> pkdata = preprocess_be(data);
julia> combine(groupby(pkdata, :formulation), within_subject_variability)
2×3 DataFrame
Row │ formulation σw k
│ Cat… Float64 Float64
─────┼─────────────────────────────────
1 │ R 0.0800952 15.0
2 │ T 0.108075 14.0
julia> data = dataset(joinpath("bioequivalence", "RRT_RTR_TRR", "SLTGSF2020_DS02"));
julia> pkdata = preprocess_be(data, endpoint = :PK);
julia> combine(groupby(pkdata, :formulation), t -> within_subject_variability(t; allownonreplicated=true))
2×3 DataFrame
Row │ formulation σw k
│ Cat… Float64? Float64?
─────┼────────────────────────────────────────
1 │ R 0.113973 21.0
2 │ T missing missing
Bioequivalence.within_subject_variability_ratio
— Functionwithin_subject_variability_ratio(
σ::AbstractVector{<:Union{Real, Missing}},
k::AbstractVector{<:Union{Real, Missing}},
level::Real = 0.95
) -> Vector{NamedTuple{(:σ_ratio, :σ⁺), ...}}
within_subject_variability_ratio(
data::AbstractDataFrame,
level::Real = 0.95
) -> DataFrame
Return the within-subject variability ratio and upper bounds. σ
contains the estimated within subject variability. k
contains the associated degrees of freedom. level
determines the confidence level for the upper bound.
Examples
julia> data = dataset(joinpath("bioequivalence", "RTTR_TRRT", "PJ2017_4_3"));
julia> pkdata = preprocess_be(data);
julia> wsv_estimates = combine(groupby(pkdata, :formulation), within_subject_variability)
2×3 DataFrame
Row │ formulation σw k
│ Cat… Float64 Float64
─────┼─────────────────────────────────
1 │ R 0.0800952 15.0
2 │ T 0.108075 14.0
julia> within_subject_variability_ratio(wsv_estimates[!, :σw], wsv_estimates[!, :k])
1-element Vector{@NamedTuple{σ_ratio::Float64, σ⁺::Float64}}:
(σ_ratio = 1.349328424089969, σ⁺ = 2.1176303305572595)
julia> within_subject_variability_ratio(wsv_estimates)
2×5 DataFrame
Row │ formulation σw k σ_ratio σ⁺
│ Cat… Float64 Float64 Float64? Float64?
─────┼───────────────────────────────────────────────────────────────
1 │ R 0.0800952 15.0 missing missing
2 │ T 0.108075 14.0 1.34933 2.11763