Helmut
★★★

Vienna, Austria,
2020-11-05 13:30
(218 d 23:09 ago)

Posting: # 22059
Views: 1,146

## partial AUCs [NCA / SHAM]

Dear all,

since partial AUC are required for some MR-products, I’m facing a increasing number of miscalculations in reports…
For users of Phoenix/WinNonlin: Please RTFM (User’s Guide → Noncompartmental Analysis → Partial areas).
If we split the AUC at certain (≥1) cut-off time(s), the sum of partial AUCs should equal AUC0–t. If not, something went wrong in the calculation.

Let’s explore a recent example. A multiphasic release product, cut-off time 4 h, linear-up / logarithmic-down trapezoidal method (data at the end):

Correct:

AUC0–t = 980.78 ng/mL, pAUC0–4 = 54.05 ng/mL, pAUC4–72 = 926.73 ng/mL; Σ pAUC = AUC0–t✔️

Reported:

AUC0–t = 980.78 ng/mL, pAUC0–4 = 54.05 ng/mL, pAUC4–72 = 966.33 ng/mL; Σ pAUC > AUC0–t

What’s going on here? The CRO split the data set at four hours and performed separate NCAs on the splits. Works fine for the first one but fails for the second because naturally all time points <4 h are missing and the software automatically added t=0 and C=0. Consequently the area of the triangle given by $$\small{t_0|C_0,\,t_4|C_0,\,t_4|C_4}$$ was added: $$\small{AUC_{\textit{i}-\textit{i}+1}=\frac{1}{2}(t_{\textit{i}+1}-t_\textit{i})(C_{\textit{i}+1}+C_\textit{i})=\frac{1}{2}(4-0)(19.80+0)=2\times19.80=39.60}$$.

I asked the CRO for the project-file to check. Of course, the “Core output” contained the information:
   Time       Conc.      AUC       h       ng/mL    h*ng/mL ------------------------------  0.0000 @    0.0000    0.0000  4.000      19.80     39.60  4.500      22.80     50.25 ... @) Note - the concentration at dose time was added for extrapolation purposes.

You can’t avoid that. If you think about adding a concentration 0 at 4 hours, you would be punished by

and
*** ERROR 14062: Duplicate time values on data file. Please ensure you have defined a unique profile

There’s another flaw when splitting the data set in case of missings and/or deviations from scheduled sampling time points. Even when the split is performed on the scheduled ones, one might end up with an apples-and-oranges comparison. Contrary to that, partial AUCs in PHX/WNL are calculated exactly for the specified start- / end-times and inter-/extrapolated according to the selected AUC method.

AFAIK, partial AUCs were introduced in PHX/WNL 6.0 (2009!). In earlier versions one has to work with split data sets. In all but the first one: Generate a new column where e.g., new.time = time – cut-off and map this one to time in NCA.

Data and correct calculation:
 t       C   Δ C  Δ AUC  AUC0–t   pAUC4–t  0      0.00       0.00   0.00  0.5    0.00  ↔    0.00   0.00  1      7.23  ↑    1.81   1.81  1.25  10.10  ↑    2.17   3.97  1.5   12.80  ↑    2.86   6.84  1.75  17.60  ↑    3.80   10.64  2     21.50  ↑    4.89   15.52  2.25  18.60  ↓    5.00   20.53  2.5   20.40  ↑    4.88   25.40  3     18.60  ↓    9.74   35.15  3.5   18.60  ↔    9.30   44.45  4     19.80  ↑    9.60   54.05    0.00  4.5   22.80  ↑   10.65   64.70   10.65  5     27.30  ↑   12.53   77.22   23.18  5.5   34.00  ↑   15.33   92.55   38.50  6     40.00  ↑   18.50  111.05   57.00  6.5   38.00  ↓   19.50  130.54   76.50  7     37.30  ↓   18.82  149.37   95.32  7.5   36.30  ↓   18.40  167.76  113.72  8     34.90  ↓   17.80  185.56  131.52  9     35.30  ↑   35.10  220.66  166.92 12     28.30  ↓   95.01  315.68  261.63 24     18.00  ↓  273.16  588.83  534.79 36     11.10  ↓  171.28  760.11  706.06 48      7.01  ↓  106.79  866.90  812.85 72      3.03  ↓  113.88  980.78  926.73   54.05 + 926.73 = 980.78 ✔️

Wrong after splitting (where the first split with AUC0–4 = 54.05 is correct):
 t       C   Δ C  Δ AUC  AUC0–t  0 @    0.00       0.00    0.00  ← automatically added  4     19.80  ↑   39.60   39.60  4.5   22.80  ↑   10.65   50.25  5     27.30  ↑   12.53   62.78  5.5   34.00  ↑   15.33   78.10  6     40.00  ↑   18.50   96.60  6.5   38.00  ↓   19.50  116.10  7     37.30  ↓   18.82  134.92  7.5   36.30  ↓   18.40  153.32  8     34.90  ↓   17.80  171.12  9     35.30  ↑   35.10  206.22 12     28.30  ↓   95.01  301.23 24     18.00  ↓  273.16  574.39 36     11.10  ↓  171.28  745.66 48      7.01  ↓  106.79  852.45 72      3.03  ↓  113.88  966.33   54.05 + 966.33 = 1020.38 > 980.73 ❌

Dif-tor heh smusma 🖖
Helmut Schütz

The quality of responses received is directly proportional to the quality of the question asked. 🚮
Science Quotes
dshah
★

India,
2020-11-05 13:39
(218 d 23:00 ago)

@ Helmut
Posting: # 22060
Views: 991

## partial AUCs

Greetings All!
I believe we are using real time for PK characterization, so if some subject's time point does not match- it may show some difference for partial AUC's. This is my thought as currently I do not have Phoenix.
Regards,
Dshah
Helmut
★★★

Vienna, Austria,
2020-11-05 14:15
(218 d 22:23 ago)

@ dshah
Posting: # 22061
Views: 990

## partial AUCs

Hi Dshah,

» I believe we are using real time for PK characterization, …

I hope that everybody does.

» … so if some subject's time point does not match- it may show some difference for partial AUC's.

I think so.

» This is my thought as currently I do not have Phoenix.

Which software are you using and – more specifically – how are later partial AUCs calculated?

Dif-tor heh smusma 🖖
Helmut Schütz

The quality of responses received is directly proportional to the quality of the question asked. 🚮
Science Quotes
PharmCat
★

Russia,
2020-11-13 01:16
(211 d 11:23 ago)

@ Helmut
Posting: # 22066
Views: 766

## partial AUCs

Hi Helmut,

I don't think that Certara (Phoenix) is not motivated to do better software. Look at LMM library - this is ancient as mammoth excrement and should be rewritten years ago (it is a big luck that we have much memory and CPU time, but this still doesn't work for a large number of observations).

So... In Julia this calculated fine:
Code:
 df = CSV.file("pkpart.csv") |> DataFrame pkds       = ClinicalTrialUtilities.pkimport(df; conc = :conc, time = :time) pk         = ClinicalTrialUtilities.nca!(pkds, calcm = :luld) println("AUCall: ", pk[1, :AUCall]) pall = pk[1, :AUCall] ClinicalTrialUtilities.setdosetime!(pkds, ClinicalTrialUtilities.DoseTime(dose = 120, time = 0, tau = 4)) pk         = ClinicalTrialUtilities.nca!(pkds, calcm = :luld) println("AUCtau 0 - 4: ", pk[1, :AUCtau]) p1 = pk[1, :AUCtau] ClinicalTrialUtilities.setdosetime!(pkds, ClinicalTrialUtilities.DoseTime(dose = 120, time = 4, tau = 72-4)) pk         = ClinicalTrialUtilities.nca!(pkds, calcm = :luld) println("AUCtau 4 - 72: ", pk[1, :AUCtau]) p2 = pk[1, :AUCtau] println("Check pall ≈ p1 + p2: ", pall ≈ p1 + p2) 

Out:
 julia> AUCall: 980.7754537633873 AUCtau 0 - 4: 54.04557219475543 AUCtau 4 - 72: 926.7298815686318 Check pall ≈ p1 + p2: true