using DataFramesMeta
using Pumas
using PharmaDatasets
using Random
using CairoMakie
using AlgebraOfGraphics
Introduction to Superposition in Pumas
Load the necessary libraries
1 Introduction
This tutorial will introduce the workflow of performing Superposition (SP) in a command-line based workflow which simulates concentration-time profiles following multiple dosing events based on single-dose data. A graphical user interface for SP is also available for a more interactive experience. Please contact sales@pumas.ai for more information.
For the purpose of this tutorial, we will be using the following dataset:
Blood samples for pharmacokinetics were collected in 30 subjects who received 250 mg, 500 mg and 750 mg of DrugX as a single dose for 24 hours post dose.
We will perform superposition using the single dose data for each dosing group.
In the given dataset
- Time = hrs
- Conc = ug/L
- Amt = ug
1.1 Load Data
Load the pharmacokinetic (PK) dataset using the datasets
function from PharmaDatasets
.
= dataset("iv_sd_1")
sd_pk = @rsubset sd_pk :dose == 250;
sd_pk_250 first(sd_pk, 5)
Row | id | dose | time | conc | amt | route |
---|---|---|---|---|---|---|
Int64 | Int64 | Float64 | Float64 | Int64? | String3 | |
1 | 1 | 250 | 0.0 | 17.29 | 250 | iv |
2 | 1 | 250 | 0.25 | 17.87 | missing | iv |
3 | 1 | 250 | 0.5 | 25.59 | missing | iv |
4 | 1 | 250 | 0.75 | 19.52 | missing | iv |
5 | 1 | 250 | 1.0 | 18.72 | missing | iv |
2 Superposition in Pumas
The NCA.superposition function in Pumas can be used to simulate drug concentration profiles after multiple dosing events, based on single-dose data. Superposition analysis is especially useful for predicting steady-state concentrations without having to collect data from multiple dosing trials. Here, we will explore the details of each parameter involved in the NCA.superposition
function, walk through its use, and provide examples to help you understand how to apply it in practice.
2.1 Function Overview: NCA.superposition
superposition(
NCA.::Union{NCAPopulation,NCASubject};
data
ii,= 5,
ndoses = nothing,
amt = 3e-2,
steadystatetol = :linear,
method )
This function calculates the superposition of concentration profiles from single-dose data, simulating what would happen after repeated dosing. The superposition technique assumes that the pharmacokinetics of the drug remain linear and predictable across multiple doses.
2.1.1 Arguments:
ii
- Interdose Interval (Required)- The interdose interval (
ii
) is the time between consecutive doses. This is a crucial parameter because it dictates how often the drug is administered. - In practice, this value is typically provided in hours or days. For example, if a drug is dosed once daily, you would set
ii = 24
(assuming time is measured in hours).
Example:
= 24 # Once-a-day dosing ii
- The interdose interval (
ndoses
- Number of Doses (Optional)ndoses
specifies the total number of doses administered. This can either be a positive integer or infinity (Inf
). Settingndoses = Inf
simulates drug administration until steady-state is reached.- If the number of doses is set to a finite number (e.g.,
ndoses = 5
), the function will calculate the concentration-time profile up to the specified number of doses.
Example:
= 7 # Administer 7 doses ndoses
amt
- Dose Amount (Optional)- This parameter defines the amount of drug administered with each dose. If not provided, the function uses the dose amount from the original dataset (e.g.,
AMT
). - Specifying
amt
allows you to simulate superposition for different dosing levels without altering the original dataset.
Example:
= 20000 # Set dose to 20,000 units amt
- This parameter defines the amount of drug administered with each dose. If not provided, the function uses the dose amount from the original dataset (e.g.,
steadystatetol
- Steady-State Tolerance (Optional)- The steady-state tolerance controls how close the concentration profile must be to the steady-state condition before the function terminates further dose additions.
- Steady-state is typically reached when the difference between drug concentration after two consecutive doses is within a small margin of error. This is defined by the formula: [ | 1 - | ]
- The default value is
3e-2
(or 3%). You can adjust this parameter based on the precision required for your analysis.
Example:
= 1e-2 # Set tolerance to 1% steadystatetol
method
- Interpolation Method (Optional)- The method parameter defines how the concentration values are interpolated between observed data points. The default method is
:linear
, meaning the function will use linear interpolation to predict concentrations at unmeasured time points.
Example:
= :linear # Use linear interpolation method
- The method parameter defines how the concentration values are interpolated between observed data points. The default method is
3 How Superposition Works
The superposition principle is based on the concept of linear pharmacokinetics, where the concentration profile following multiple dosing events can be predicted by summing up the individual contributions of each dose. This means the concentration at any given time point after multiple doses is simply the sum of the concentrations produced by each individual dose, shifted by the interdose interval (ii
).
4 Example Workflow: Superposition for a 7-Day Dosing Regimen
Let’s walk through a practical example where we simulate the concentration-time profile after a 7-day dosing regimen with a once-daily (24-hour interval) dosing schedule.
4.1 Step 1: Prepare Your NCA Population
First, you need to prepare an NCA population (NCAPopulation
) from the observed data. This involves using the read_nca
function to load the dataset and specify the important variables (e.g., time, dose, observations):
= read_nca(
nca_pop # DataFrame containing PK data
sd_pk_250, = :id, # Subject ID
id = :time, # Time column
time = :conc, # Drug concentration column
observations = :amt, # Dose amount
amt = :route, # Dosing route (e.g., iv or ev)
route )
NCAPopulation (10 subjects):
Number of missing observations: 0
Number of blq observations: 0
4.2 Step 2: Run Superposition Analysis
Next, run the superposition analysis for a 7-day, once-daily dosing regimen:
= NCA.superposition(nca_pop, ii = 24, ndoses = 7, amt = 20000) result
Row | id | abstime | time | observations | amt | ii | addl | route | occasion |
---|---|---|---|---|---|---|---|---|---|
String | Float64 | Float64 | Float64 | Int64 | Int64? | Int64? | String | Int64 | |
1 | 1 | 0.0 | 0.0 | 1383.2 | 20000 | 24 | 6 | iv | 1 |
2 | 1 | 0.25 | 0.25 | 1429.6 | 0 | missing | missing | iv | 1 |
3 | 1 | 0.5 | 0.5 | 2047.2 | 0 | missing | missing | iv | 1 |
4 | 1 | 0.75 | 0.75 | 1561.6 | 0 | missing | missing | iv | 1 |
5 | 1 | 1.0 | 1.0 | 1497.6 | 0 | missing | missing | iv | 1 |
6 | 1 | 1.5 | 1.5 | 1579.2 | 0 | missing | missing | iv | 1 |
7 | 1 | 2.0 | 2.0 | 1344.0 | 0 | missing | missing | iv | 1 |
8 | 1 | 2.5 | 2.5 | 1500.8 | 0 | missing | missing | iv | 1 |
9 | 1 | 3.0 | 3.0 | 1369.6 | 0 | missing | missing | iv | 1 |
10 | 1 | 4.0 | 4.0 | 996.0 | 0 | missing | missing | iv | 1 |
11 | 1 | 6.0 | 6.0 | 840.8 | 0 | missing | missing | iv | 1 |
12 | 1 | 8.0 | 8.0 | 684.0 | 0 | missing | missing | iv | 1 |
13 | 1 | 12.0 | 12.0 | 525.6 | 0 | missing | missing | iv | 1 |
⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ |
1049 | 10 | 145.0 | 1.0 | 2303.9 | 0 | missing | missing | iv | 7 |
1050 | 10 | 145.5 | 1.5 | 2215.64 | 0 | missing | missing | iv | 7 |
1051 | 10 | 146.0 | 2.0 | 2334.7 | 0 | missing | missing | iv | 7 |
1052 | 10 | 146.5 | 2.5 | 1813.06 | 0 | missing | missing | iv | 7 |
1053 | 10 | 147.0 | 3.0 | 1403.52 | 0 | missing | missing | iv | 7 |
1054 | 10 | 148.0 | 4.0 | 1722.27 | 0 | missing | missing | iv | 7 |
1055 | 10 | 150.0 | 6.0 | 708.507 | 0 | missing | missing | iv | 7 |
1056 | 10 | 152.0 | 8.0 | 569.01 | 0 | missing | missing | iv | 7 |
1057 | 10 | 156.0 | 12.0 | 215.102 | 0 | missing | missing | iv | 7 |
1058 | 10 | 160.0 | 16.0 | 81.0722 | 0 | missing | missing | iv | 7 |
1059 | 10 | 164.0 | 20.0 | 36.9055 | 0 | missing | missing | iv | 7 |
1060 | 10 | 168.0 | 24.0 | 12.0409 | 0 | missing | missing | iv | 7 |
ii=24
: The drug is administered once every 24 hours.ndoses=7
: We are simulating a 7-day dosing schedule.amt=20000
: Each dose consists of 20,000 units of the drug.
4.3 Step 3: Visualize the Superposition Results
After running the superposition, you can visualize the predicted concentration-time profiles. You might want to plot the results to compare steady-state behavior:
# Example: Use AlgebraOfGraphics for plotting
=
plt data(result) *
mapping(:abstime, :observations, group = :id) *
visual(Lines, color = (:grey, 0.5))
draw(
plt;= (;
axis = "Time (hours)",
xlabel = "Observations (ug/L)",
ylabel = 0:12:160,
xticks = 0:500:4000,
yticks
), )
In this plot, you’ll observe how the drug concentrations change over time with each subsequent dose. By day 7, the drug may reach steady-state, meaning the concentration profile no longer changes significantly from one dose to the next.
4.4 Step 4: Investigate Steady-State Achievements
To understand if the system has reached steady-state, you can adjust the steadystatetol parameter. This allows you to set a stricter or more lenient criterion for steady-state achievement.
= NCA.superposition(nca_pop, ii = 24, ndoses = Inf, steadystatetol = 1e-3) result_strict_tol
[ Info: Subject 1: ndoses is not specified. So 0.001 is used as the steady state tolerance (can be passed in as an argument, e.g. `steadystatetol = 0.001`)
[ Info: Subject 2: ndoses is not specified. So 0.001 is used as the steady state tolerance (can be passed in as an argument, e.g. `steadystatetol = 0.001`)
[ Info: Subject 3: ndoses is not specified. So 0.001 is used as the steady state tolerance (can be passed in as an argument, e.g. `steadystatetol = 0.001`)
[ Info: Subject 4: ndoses is not specified. So 0.001 is used as the steady state tolerance (can be passed in as an argument, e.g. `steadystatetol = 0.001`)
[ Info: Subject 5: ndoses is not specified. So 0.001 is used as the steady state tolerance (can be passed in as an argument, e.g. `steadystatetol = 0.001`)
[ Info: Subject 6: ndoses is not specified. So 0.001 is used as the steady state tolerance (can be passed in as an argument, e.g. `steadystatetol = 0.001`)
[ Info: Subject 7: ndoses is not specified. So 0.001 is used as the steady state tolerance (can be passed in as an argument, e.g. `steadystatetol = 0.001`)
[ Info: Subject 8: ndoses is not specified. So 0.001 is used as the steady state tolerance (can be passed in as an argument, e.g. `steadystatetol = 0.001`)
[ Info: Subject 9: ndoses is not specified. So 0.001 is used as the steady state tolerance (can be passed in as an argument, e.g. `steadystatetol = 0.001`)
[ Info: Subject 10: ndoses is not specified. So 0.001 is used as the steady state tolerance (can be passed in as an argument, e.g. `steadystatetol = 0.001`)
Row | id | abstime | time | observations | amt | ii | addl | route | occasion |
---|---|---|---|---|---|---|---|---|---|
String | Float64 | Float64 | Float64 | Int64 | Int64? | Int64? | String | Int64 | |
1 | 1 | 0.0 | 0.0 | 17.29 | 250 | 24 | 3 | iv | 1 |
2 | 1 | 0.25 | 0.25 | 17.87 | 0 | missing | missing | iv | 1 |
3 | 1 | 0.5 | 0.5 | 25.59 | 0 | missing | missing | iv | 1 |
4 | 1 | 0.75 | 0.75 | 19.52 | 0 | missing | missing | iv | 1 |
5 | 1 | 1.0 | 1.0 | 18.72 | 0 | missing | missing | iv | 1 |
6 | 1 | 1.5 | 1.5 | 19.74 | 0 | missing | missing | iv | 1 |
7 | 1 | 2.0 | 2.0 | 16.8 | 0 | missing | missing | iv | 1 |
8 | 1 | 2.5 | 2.5 | 18.76 | 0 | missing | missing | iv | 1 |
9 | 1 | 3.0 | 3.0 | 17.12 | 0 | missing | missing | iv | 1 |
10 | 1 | 4.0 | 4.0 | 12.45 | 0 | missing | missing | iv | 1 |
11 | 1 | 6.0 | 6.0 | 10.51 | 0 | missing | missing | iv | 1 |
12 | 1 | 8.0 | 8.0 | 8.55 | 0 | missing | missing | iv | 1 |
13 | 1 | 12.0 | 12.0 | 6.57 | 0 | missing | missing | iv | 1 |
⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ |
494 | 10 | 49.0 | 1.0 | 28.7988 | 0 | missing | missing | iv | 3 |
495 | 10 | 49.5 | 1.5 | 27.6955 | 0 | missing | missing | iv | 3 |
496 | 10 | 50.0 | 2.0 | 29.1837 | 0 | missing | missing | iv | 3 |
497 | 10 | 50.5 | 2.5 | 22.6633 | 0 | missing | missing | iv | 3 |
498 | 10 | 51.0 | 3.0 | 17.544 | 0 | missing | missing | iv | 3 |
499 | 10 | 52.0 | 4.0 | 21.5284 | 0 | missing | missing | iv | 3 |
500 | 10 | 54.0 | 6.0 | 8.85634 | 0 | missing | missing | iv | 3 |
501 | 10 | 56.0 | 8.0 | 7.11263 | 0 | missing | missing | iv | 3 |
502 | 10 | 60.0 | 12.0 | 2.68877 | 0 | missing | missing | iv | 3 |
503 | 10 | 64.0 | 16.0 | 1.0134 | 0 | missing | missing | iv | 3 |
504 | 10 | 68.0 | 20.0 | 0.461319 | 0 | missing | missing | iv | 3 |
505 | 10 | 72.0 | 24.0 | 0.150512 | 0 | missing | missing | iv | 3 |
In this example, the simulation will stop only when the concentration profile satisfies the 0.1% tolerance for steady-state. This is useful for simulating long-term dosing regimens and understanding how steady-state concentrations are achieved.
5 Performing NCA on Superposition Result
The result of the superposition analysis can easily be sent to compute NCA metrics.
= read_nca(
nca_sup
result,= :occasion,
group = :ii,
ii = :observations,
observations = :time,
time = :amt,
amt = :route,
route )
NCAPopulation (10 subjects):
Group: [["occasion" => 1], ["occasion" => 2], ["occasion" => 3], ["occasion" => 4], ["occasion" => 5], ["occasion" => 6], ["occasion" => 7]]
Number of missing observations: 0
Number of blq observations: 0
Once the result of the superposition data is read into Pumas as a NCA dataset, we can run NCA on this.
= run_nca(
nca_sup_result
nca_sup,= [:cmax, :cmaxss, :cmin, :cminss, :accumulation_index, :cavgss],
parameters = "NCA results based on Superposition",
studytitle
); nca_sup_result.reportdf
Row | id | occasion | cmax | cmaxss | cmin | cminss | accumulation_index | cavgss |
---|---|---|---|---|---|---|---|---|
String | Int64 | Float64 | Float64 | Float64 | Float64 | Float64 | Float64 | |
1 | 1 | 1 | 2047.2 | 2199.37 | 211.2 | 226.899 | 1.07433 | 660.144 |
2 | 2 | 1 | 3436.0 | 3447.71 | 18.4 | 18.4627 | 1.00341 | 543.678 |
3 | 3 | 1 | 3512.8 | 3550.74 | 80.0 | 80.8641 | 1.0108 | 605.476 |
4 | 4 | 1 | 2738.4 | 2798.83 | 96.0 | 98.1185 | 1.02207 | 660.55 |
5 | 5 | 1 | 2544.8 | 2590.35 | 88.0 | 89.5752 | 1.0179 | 654.691 |
6 | 6 | 1 | 1920.8 | 1946.36 | 104.0 | 105.384 | 1.01331 | 494.529 |
7 | 7 | 1 | 3153.6 | 3161.8 | 17.6 | 17.6457 | 1.0026 | 490.443 |
8 | 8 | 1 | 2688.0 | 2803.81 | 98.4 | 102.639 | 1.04308 | 549.773 |
9 | 9 | 1 | 2425.6 | 2464.79 | 68.8 | 69.9116 | 1.01616 | 627.842 |
10 | 10 | 1 | 3076.8 | 3089.31 | 36.8 | 36.9497 | 1.00407 | 599.588 |
11 | 1 | 2 | 2186.74 | 2350.94 | 228.552 | 245.715 | 1.07509 | 717.879 |
12 | 2 | 2 | 3440.8 | 3452.52 | 18.4221 | 18.4848 | 1.00341 | 544.434 |
13 | 3 | 2 | 3555.66 | 3594.25 | 81.3085 | 82.1908 | 1.01085 | 616.165 |
⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ |
59 | 9 | 6 | 2453.46 | 2492.9 | 69.4373 | 70.5535 | 1.01607 | 634.527 |
60 | 10 | 6 | 3087.5 | 3100.05 | 36.9055 | 37.0556 | 1.00406 | 601.74 |
61 | 1 | 7 | 2198.36 | 2381.56 | 159.457 | 172.746 | 1.08334 | 730.869 |
62 | 2 | 7 | 3440.81 | 3446.21 | 4.80753 | 4.81508 | 1.00157 | 543.876 |
63 | 3 | 7 | 3556.29 | 3608.28 | 45.4549 | 46.1194 | 1.01462 | 619.67 |
64 | 4 | 7 | 2805.94 | 2875.91 | 72.9751 | 74.7949 | 1.02494 | 688.462 |
65 | 5 | 7 | 2595.05 | 2651.35 | 52.3107 | 53.4456 | 1.02169 | 671.535 |
66 | 6 | 7 | 1997.71 | 2087.55 | 76.9095 | 80.3684 | 1.04497 | 533.38 |
67 | 7 | 7 | 3159.63 | 3167.78 | 6.41651 | 6.43305 | 1.00258 | 491.655 |
68 | 8 | 7 | 2743.13 | 2838.27 | 57.1145 | 59.0954 | 1.03468 | 564.933 |
69 | 9 | 7 | 2453.46 | 2477.16 | 30.6937 | 30.9902 | 1.00966 | 632.726 |
70 | 10 | 7 | 3087.5 | 3098.03 | 12.0409 | 12.082 | 1.00341 | 601.239 |
6 Practical Applications of Superposition
Superposition analysis is widely used in pharmacokinetics for the following purposes:
Dosing Regimen Design:
- Helps to predict the concentration profile of a drug after multiple doses and determine whether therapeutic concentrations are achieved and maintained.
Steady-State Prediction:
- Essential for drugs that require steady-state concentrations for efficacy, such as chronic therapies or antibiotics.
Dose Adjustment:
- By adjusting the
amt
parameter, superposition can help simulate different dose levels and guide decisions on appropriate dosing adjustments.
- By adjusting the
Interdose Interval Analysis:
- By varying the
ii
parameter, you can simulate different dosing intervals (e.g., twice daily vs. once daily) to optimize the regimen for efficacy and safety.
- By varying the
7 Conclusion
The NCA.superposition
function in Pumas is a flexible and essential tool for pharmacokinetic modeling. By simulating drug concentration profiles under repeated dosing, you can make informed decisions about dosing regimens, steady-state predictions, and dose adjustments. With this detailed understanding of the function parameters and a step-by-step approach, you can apply superposition analysis effectively to your own datasets.