# The NCA Functions

The NCA functions can perform calculations on both NCAPopulation and NCASubject. When the input is a NCAPopulation, then the output is a DataFrame, and when the input is a NCASubject, the output is a number.

Tip

All functions are accessed from within the NCA submodule. For example, to use auc on NCAPopulation, one would use NCA.auc(pop).

The following keyword arguments apply to all NCA functions:

• interval takes a tuple of two numbers like (1., 10.) which will compute the quantity in the time interval, or nothing which will compute the quantity in the entire time span. Default is nothing
• normalize (normalize with respect to dosage) takes true or false. Default is false.
• auctype (types of AUC) takes :inf or :last. Default is :inf.
• method takes :linear, :linuplogdown, or :linlog. Default is :linear
• pred (predicted) takes true or false. Default is false.
• threshold sets the number for the maximum number of points that can be used for lambdaz calculation.

### NCA Function List

We will use this example dataset to illustrate the use of the functions below.

julia> df = DataFrame(id = [1,1,1,1,1,1,2,2,2,2,2,2,2],
time = [0,1,2,3,4,6, 0,1,2,3,4,6,8],
amt=[10,0,0,0,0,0,20,0,0,0,0,0,0],
sss=[1,0,0,0,0,0,1,0,0,0,0,0,0],
iii=[4,0,0,0,0,0,4,0,0,0,0,0,0],
conc=[missing,8,6,4,2,0.1,missing,2,6,3,2,0.5,0.1],
isblq = [0,0,0,0,0,1,0,0,0,0,0,0,1],
route = ["iv","iv","iv","iv","iv","iv","ev","ev","ev","ev","ev","ev", "ev"])13×8 DataFrame
Row │ id     time   amt    sss    iii    conc       isblq  route
│ Int64  Int64  Int64  Int64  Int64  Float64?   Int64  String
─────┼─────────────────────────────────────────────────────────────
1 │     1      0     10      1      4  missing        0  iv
2 │     1      1      0      0      0        8.0      0  iv
3 │     1      2      0      0      0        6.0      0  iv
4 │     1      3      0      0      0        4.0      0  iv
5 │     1      4      0      0      0        2.0      0  iv
6 │     1      6      0      0      0        0.1      1  iv
7 │     2      0     20      1      4  missing        0  ev
8 │     2      1      0      0      0        2.0      0  ev
9 │     2      2      0      0      0        6.0      0  ev
10 │     2      3      0      0      0        3.0      0  ev
11 │     2      4      0      0      0        2.0      0  ev
12 │     2      6      0      0      0        0.5      0  ev
13 │     2      8      0      0      0        0.1      1  ev

To illustrate the use of different functions in varying scenarios, we will use four versions of read_nca.

The first is a standard format where we don't use additional options.

julia> df_r1 = read_nca(df, observations = :conc)NCAPopulation (2 subjects):
Number of missing observations: 2
Number of blq observations: 0

In the second format, we let Pumas-NCA know that there is a blq column. This results in some observations being counted as blq and some as missing.

julia> df_r2 = read_nca(df, observations = :conc, blq = :isblq)[ Info: Rows with isblq as 1 are removed from the data, for more control over BLQ handling please refer to concblq kwarg
NCAPopulation (2 subjects):
Number of missing observations: 2
Number of blq observations: 2

In the third format, we specify that the dose is steady-state, sss, and the frequency to be iii.

julia> df_r3 = read_nca(df, observations = :conc, ii = :iii, ss = :sss)NCAPopulation (2 subjects):
Number of missing observations: 2
Number of blq observations: 0

Lastly, in addition to specifying the steady-state nature and frequency, we also map the isblq column.

julia> df_r4 = read_nca(df, observations = :conc, ii = :iii, ss = :sss, blq = :isblq)[ Info: Rows with isblq as 1 are removed from the data, for more control over BLQ handling please refer to concblq kwarg
NCAPopulation (2 subjects):
Number of missing observations: 2
Number of blq observations: 2

#### n_samples(subj)

The number of measurements that are above the lower limit of quantification.

When isblq is not mapped, below is the result:

julia> NCA.n_samples(df_r1)2×2 DataFrame
Row │ id     n_samples
│ Int64  Int64
─────┼──────────────────
1 │     1          5
2 │     2          6

When isblq is mapped, below is the result where you see the number of blq points.

julia> NCA.n_samples(df_r2)2×2 DataFrame
Row │ id     n_samples
│ Int64  Int64
─────┼──────────────────
1 │     1          4
2 │     2          5

When called on only the first subject by indexing into the NCAPopulation, df_r1 we get a number

julia> NCA.n_samples(df_r1)5

#### dosetype(subj)

julia> NCA.dosetype(df_r1)2×2 DataFrame
Row │ id     dosetype
│ Int64  String
─────┼─────────────────
1 │     1  IVBolus
2 │     2  EV

#### tau(subj)

Provides the dosing interval provided by ii

In the first example as ii is not passed, we get a value of missing.

julia> NCA.tau(df_r1)2×2 DataFrame
Row │ id     tau
│ Int64  Missing
─────┼────────────────
1 │     1  missing
2 │     2  missing

And below, as we map the iii column to ii the tau is determined.

julia> NCA.tau(df_r3)2×2 DataFrame
Row │ id     tau
│ Int64  Int64
─────┼──────────────
1 │     1      4
2 │     2      4

#### doseamt(subj)

The amount of dose given to each subject.

julia> NCA.doseamt(df_r1)2×2 DataFrame
Row │ id     doseamt
│ Int64  Int64
─────┼────────────────
1 │     1       10
2 │     2       20

#### lambdaz

lambdaz(subj;
threshold=100,
idxs=nca.lambdazidxs,
slopetimes=nca.lambdazslopetimes,
recompute=true,
verbose=true,
kwargs...)

Terminal elimination rate constant ($λz$). This is core function of NCA that computes the terminal rate constant. A list of considerations for computing $λz$ are listed below.

1. By default, Pumas-NCA uses an iterative best fit regression method to choose the terminal slope that provides the best adjusted r-square ($adjr2factor$) value. The iterative algorithm converges when the change in $adjr2factor$ is 0.0001 or less.
2. $λz$ computation requires at least three data points to provides a valid result
3. The algorithm tries its best to not use the time at tmax to compute the $λz$, and if it does, a warning is provided.

Regular users of Pumas-NCA don't usually have to adjust any of the settings for computing the $λz$, as a best decision is made automatically. However, if there is a desire to experiment given the experimental context, certain arguments are provided that are discussed below with specific examples.

julia> NCA.lambdaz(df_r1)2×2 DataFrame
Row │ id     lambdaz
│ Int64  Float64
─────┼─────────────────
1 │     1  1.26795
2 │     2  0.748933

$adjr2factor$ can be relaxed to to fit a best-fit earlier. Note in the example below, a 100 fold difference in the value results in different results of terminal slope for id=1.

julia> NCA.lambdaz(df_r1, adjr2factor=0.1)2×2 DataFrame
Row │ id     lambdaz
│ Int64  Float64
─────┼─────────────────
1 │     1  0.871274
2 │     2  0.690867

threshold defines the maximum number of points that can be used to compute the $λz$. Currently, the default is set to 100 points, that satisfies most use cases, but if there is a need to adjust one can do so.

Info

The iterative best-fit regression is bounded to produce a result that satisfies the threshold value, so it is normal to see a lower $r^2$ value

When the thershold is set to 2 in the example below, Pumas-NCA warns that it cannot compute the $λz$ which requires a minimum of three points.

julia> NCA.lambdaz(df_r1, threshold=2)[ Info: ID 1 errored: lambdaz calculation needs at least three data points between Cmax and the last positive concentration
[ Info: ID 2 errored: lambdaz calculation needs at least three data points between Cmax and the last positive concentration
2×2 DataFrame
Row │ id     lambdaz
│ Int64  Missing
─────┼────────────────
1 │     1  missing
2 │     2  missing

idxs and slopetimes are both used to manually pick and choose the data points used for terminal slope computations. Values are passed as an array of points, either indices of the time vector for idxs or the actual times in the case of slopetimes. If a single array is passed, then the same values are used across the population on every subject.

julia> NCA.lambdaz(df_r1, idxs = [2,3,4])2×2 DataFrame
Row │ id     lambdaz
│ Int64  Float64
─────┼─────────────────
1 │     1  0.549306
2 │     2  0.549306
julia> NCA.lambdaz(df_r1, slopetimes = [2,3,4])2×2 DataFrame
Row │ id     lambdaz
│ Int64  Float64
─────┼─────────────────
1 │     1  0.549306
2 │     2  0.549306

If the user has a custom array that identifies specific indices or slopetimes for each individual, they can be passed in as an array of arrays.

The lambdaz function can also be used outside the context of a NCASubject or NCAPopulation where one can pass in a simple observation and time vector. This can be useful to do a quick linear regression or to find a slope for a x-y vector.

julia> NCA.lambdaz(collect(10:-1:1), 1:10)0.5493061443340549

#### lambdazr2(subj)

Coefficient of determination ($r²$) when calculating $λz$. Note that this quantity must be computed after calculating $λz$.

Using the example where the blq is not mapped, we get the result below.

julia> NCA.lambdaz(df_r1)2×2 DataFrame
Row │ id     lambdaz
│ Int64  Float64
─────┼─────────────────
1 │     1  1.26795
2 │     2  0.748933julia> NCA.lambdazr2(df_r1)2×2 DataFrame
Row │ id     lambdazr2
│ Int64  Float64
─────┼──────────────────
1 │     1   0.975932
2 │     2   0.998154

And when the blq is mapped to isblq, the adjusted r2 changes as the number of data points changes

julia> NCA.lambdaz(df_r2)2×2 DataFrame
Row │ id     lambdaz
│ Int64  Float64
─────┼─────────────────
1 │     1  0.549306
2 │     2  0.610952julia> NCA.lambdazr2(df_r2)2×2 DataFrame
Row │ id     lambdazr2
│ Int64  Float64
─────┼──────────────────
1 │     1   0.977654
2 │     2   0.986607

#### lambdazadjr2(subj)

Adjusted coefficient of determination ($adjr²$) when calculating $λz$. Note that this quantity must be computed after calculating $λz$.

julia> NCA.lambdaz(df_r1)2×2 DataFrame
Row │ id     lambdaz
│ Int64  Float64
─────┼─────────────────
1 │     1  1.26795
2 │     2  0.748933julia> NCA.lambdazadjr2(df_r1)2×2 DataFrame
│ Int64  Float64
─────┼─────────────────────
1 │     1      0.951865
2 │     2      0.996308

#### lambdazr(subj)

Correlation coefficient ($r$) when calculating $λz$. Note that this quantity must be computed after calculating $λz$.

julia> NCA.lambdaz(df_r1)2×2 DataFrame
Row │ id     lambdaz
│ Int64  Float64
─────┼─────────────────
1 │     1  1.26795
2 │     2  0.748933julia> NCA.lambdazr(df_r1)2×2 DataFrame
Row │ id     lambdazr
│ Int64  Float64
─────┼─────────────────
1 │     1  0.987893
2 │     2  0.999077

#### lambdaznpoints(subj)

Number of points that is used in the $λz$ calculation. Note that this quantity must be computed after calculating $λz$.

julia> NCA.lambdaz(df_r1)2×2 DataFrame
Row │ id     lambdaz
│ Int64  Float64
─────┼─────────────────
1 │     1  1.26795
2 │     2  0.748933julia> NCA.lambdaznpoints(df_r1)2×2 DataFrame
Row │ id     lambdaznpoints
│ Int64  Int64
─────┼───────────────────────
1 │     1               3
2 │     2               3

#### lambdazintercept(subj)

y-intercept in the log-linear scale when calculating $λz$. Note that this quantity must be computed after calculating $λz$.

julia> NCA.lambdaz(df_r1)2×2 DataFrame
Row │ id     lambdaz
│ Int64  Float64
─────┼─────────────────
1 │     1  1.26795
2 │     2  0.748933julia> NCA.lambdazintercept(df_r1)2×2 DataFrame
Row │ id     lambdazintercept
│ Int64  Float64
─────┼─────────────────────────
1 │     1           5.42005
2 │     2           3.72607

#### lambdaztimefirst(subj)

The first time point that is used in the $λz$ calculation. Note that this quantity must be computed after calculating $λz$.

julia> NCA.lambdaz(df_r1)2×2 DataFrame
Row │ id     lambdaz
│ Int64  Float64
─────┼─────────────────
1 │     1  1.26795
2 │     2  0.748933julia> NCA.lambdaztimefirst(df_r1)2×2 DataFrame
Row │ id     lambdaztimefirst
│ Int64  Float64
─────┼─────────────────────────
1 │     1               3.0
2 │     2               4.0

#### lambdaztimelast(subj)

The last time point that is used in the $λz$ calculation. Note that this quantity must be computed after calculating $λz$.

julia> NCA.lambdaz(df_r1)2×2 DataFrame
Row │ id     lambdaz
│ Int64  Float64
─────┼─────────────────
1 │     1  1.26795
2 │     2  0.748933julia> NCA.lambdaztimelast(df_r1)2×2 DataFrame
Row │ id     lambdaztimelast
│ Int64  Float64
─────┼────────────────────────
1 │     1              6.0
2 │     2              8.0

#### thalf(subj):

Half-life.

julia> NCA.thalf(df_r1)2×2 DataFrame
Row │ id     thalf
│ Int64  Float64
─────┼─────────────────
1 │     1  0.546669
2 │     2  0.925513

Similar to the lambdaz computation, thalf can also be used on a arbitrary vector of observation and time. For example:

julia> NCA.thalf(collect(10:-1:1), 1:10, digits=3)1.2618595071429148

#### span(subj)

(lambdaztimelast(subj; kwargs...) - lambdaztimefirst(subj) / thalf(subj). Note that this quantity must be computed after calculating $λz$.

julia> NCA.lambdaz(df_r1)2×2 DataFrame
Row │ id     lambdaz
│ Int64  Float64
─────┼─────────────────
1 │     1  1.26795
2 │     2  0.748933julia> NCA.span(df_r1)2×2 DataFrame
Row │ id     span
│ Int64  Float64
─────┼────────────────
1 │     1  5.48778
2 │     2  4.32193

#### tmax(subj; interval=nothing)

Time of maximum concentration.

In the example below, notice how for the subject with iv, i.e, id = 1, the tmax is computed to 0. This is because, C0 is back-extrapolated from the observation vector whose value now represents the cmax. Hence, tmax is 0.

julia> NCA.tmax(df_r1)2×2 DataFrame
Row │ id     tmax
│ Int64  Int64
─────┼──────────────
1 │     1      0
2 │     2      2

In the event that a user wants to compute the time of maximum observation in a specific interval, they can do so by setting the interval argument to a tuple.

julia> NCA.tmax(df_r1, interval = (2,4))2×2 DataFrame
Row │ id     tmax
│ Int64  Int64
─────┼──────────────
1 │     1      2
2 │     2      2

The tmax function also works on vector of observations and time. For example:

julia> NCA.tmax(collect(10:-1:1), 0:9)0

#### cmax(subj; interval=nothing, normalize=false)

Computes the maximum concentration.

In the example below we see the difference in the cmax results across the four datasets.

1. For df_1r and df_r2 the cmax for id = 1 is the back-extrapolated value using the regression, even though that value does not exist in the original dataset. On the other hand for id = 2, the cmax is observed maximum concentration in the dataset. Note that presence of blq in df_r2 did not impact the result.
2. For df_r3, where we mapped ii and ss, the computed cmax is derived as follows: cmax/accumulationindex
3. For df_r4, in addition to mapping the ii and ss, the blq values are also specified. The computation of cmax is identical to the earlier case, however, in this case, since the number of data points is different because of blq values, the accumulation index is different.
julia> vcat(
map(x -> NCA.cmax(x),
[df_r1, df_r2, df_r3, df_r4])...,
source=:data =>"df_r".*string.(1:4)
)8×3 DataFrame
Row │ id     cmax      data
│ Int64  Float64   String
─────┼─────────────────────────
1 │     1  10.6667   df_r1
2 │     2   6.0      df_r1
3 │     1  10.6667   df_r2
4 │     2   6.0      df_r2
5 │     1  10.5998   df_r3
6 │     2   5.7      df_r3
7 │     1   9.48148  df_r4
8 │     2   5.47902  df_r4

The next example covers the computation of cmax in an interval

julia> NCA.cmax(df_r1, interval=(3,6))2×2 DataFrame
Row │ id     cmax3_6
│ Int64  Float64
─────┼────────────────
1 │     1      4.0
2 │     2      3.0

cmax can also be computed using an arbitrary array of observations and time series

julia> NCA.cmax(collect(10:-1:1), 1:10)10

The last example shows the use of the normalize argument that normalizes the derived cmax by the dose value. Compare to the first example in the cmax series. The results below are essentially dose normalized cmax of the results presented above.

julia> vcat(
map(x -> NCA.cmax(x, normalize=true),
[df_r1, df_r2, df_r3, df_r4])...,
source=:data =>"df_r".*string.(1:4)
)8×3 DataFrame
Row │ id     cmax      data
│ Int64  Float64   String
─────┼─────────────────────────
1 │     1  1.06667   df_r1
2 │     2  0.3       df_r1
3 │     1  1.06667   df_r2
4 │     2  0.3       df_r2
5 │     1  1.05998   df_r3
6 │     2  0.285     df_r3
7 │     1  0.948148  df_r4
8 │     2  0.273951  df_r4

#### cmaxss(subj; normalize=false)

Steady-state maximum concentration. If the dose is a steady-state dose specified by ss = 1, then the observed cmax is cmaxss.

In the example below, iv has the back-extrapolated cmax and ev has the observed cmax.

julia> vcat(
map(x -> NCA.cmaxss(x),
[df_r1, df_r2, df_r3, df_r4])...,
source=:data =>"df_r".*string.(1:4)
)8×3 DataFrame
Row │ id     cmaxss   data
│ Int64  Float64  String
─────┼────────────────────────
1 │     1  10.6667  df_r1
2 │     2   6.0     df_r1
3 │     1  10.6667  df_r2
4 │     2   6.0     df_r2
5 │     1  10.6667  df_r3
6 │     2   6.0     df_r3
7 │     1  10.6667  df_r4
8 │     2   6.0     df_r4

#### tmin(subj)

Time of minimal concentration after a dose.

In the example below, we can notice the difference in the time of minimum concentration when ss = 1 value towards the end fo the dosing interval. In all other cases where ss is not specified, the time at lowest observed concentration is chosen.

julia> vcat(
map(x -> NCA.tmin(x),
[df_r1, df_r2, df_r3, df_r4])...,
source=:data =>"df_r".*string.(1:4))8×3 DataFrame
Row │ id     tmin   data
│ Int64  Int64  String
─────┼──────────────────────
1 │     1      6  df_r1
2 │     2      0  df_r1
3 │     1      4  df_r2
4 │     2      0  df_r2
5 │     1      6  df_r3
6 │     2      8  df_r3
7 │     1      4  df_r4
8 │     2      6  df_r4

#### cmin(subj; normalize=false)

Minimum concentration in a dosing interval.

In the example below, for df_r1 and df_r2, the observed minimum concentrations are reported back. On the other hand, for df_r3 and df_r4, the observed minimum concentration are scaled by the accumulationindex as ss = 1

julia> vcat(
map(x -> NCA.cmin(x),
[df_r1, df_r2, df_r3, df_r4])...,
source=:data =>"df_r".*string.(1:4))8×3 DataFrame
Row │ id     cmin             data
│ Int64  Float64?         String
─────┼────────────────────────────────
1 │     1        0.1        df_r1
2 │     2  missing          df_r1
3 │     1        2.0        df_r2
4 │     2  missing          df_r2
5 │     1        0.0993729  df_r3
6 │     2        0.095      df_r3
7 │     1        1.77778    df_r4
8 │     2        0.456585   df_r4

We can also output he dose normalized values as shown in the example below,

julia> NCA.cmin(df_r1, normalize=true)2×2 DataFrame
Row │ id     cmin
│ Int64  Float64?
─────┼──────────────────
1 │     1        0.1
2 │     2  missing

### cminss(subj; normalize=false)

In the example below, the first two cases are not impacted, but where ss=1 ,the observed minimum concentration are the cminss as the dose is a steady-state dose.

julia> vcat(
map(x -> NCA.cminss(x),
[df_r1, df_r2, df_r3, df_r4])...,
source=:data =>"df_r".*string.(1:4))8×3 DataFrame
Row │ id     cminss     data
│ Int64  Float64?   String
─────┼──────────────────────────
1 │     1        0.1  df_r1
2 │     2  missing    df_r1
3 │     1        2.0  df_r2
4 │     2  missing    df_r2
5 │     1        0.1  df_r3
6 │     2        0.1  df_r3
7 │     1        2.0  df_r4
8 │     2        0.5  df_r4

#### ctau(nca::NCASubject; method=:linear)

Concentration at the end of dosing interval.

Notice in the examples below, that ctau is only computed when ii or ss is specified. Further, in both df_r3 and df_r4, the ii=4, and the last observed concentration is beyond 4, yet the function does the right thing in picking up the concentration at the end of the dosing interval tau.

julia> vcat(
map(x -> NCA.ctau(x),
[df_r1, df_r2, df_r3, df_r4])...,
source=:data =>"df_r".*string.(1:4))8×3 DataFrame
Row │ id     ctau       data
│ Int64  Float64?   String
─────┼──────────────────────────
1 │     1  missing    df_r1
2 │     2  missing    df_r1
3 │     1  missing    df_r2
4 │     2  missing    df_r2
5 │     1        2.0  df_r3
6 │     2        2.0  df_r3
7 │     1        2.0  df_r4
8 │     2        2.0  df_r4

#### cavgss(subj)

Average concentration over a dosing interval.

As expected, in the examples below, the cavgss is only computed in the cases where ii or ss is specified.

julia> vcat(
map(x -> NCA.cavgss(x),
[df_r1, df_r2, df_r3, df_r4])...,
source=:data =>"df_r".*string.(1:4))8×3 DataFrame
Row │ id     cavgss         data
│ Int64  Float64?       String
─────┼──────────────────────────────
1 │     1  missing        df_r1
2 │     2  missing        df_r1
3 │     1  missing        df_r2
4 │     2  missing        df_r2
5 │     1        6.08333  df_r3
6 │     2        3.25     df_r3
7 │     1        6.08333  df_r4
8 │     2        3.25     df_r4

#### c0(subj)

Estimate the concentration at dosing time for an IV bolus dose.

Note in the example below that this value is only computed for iv dose.

julia> NCA.c0(df_r1)2×2 DataFrame
Row │ id     c0
│ Int64  Float64?
─────┼─────────────────────
1 │     1       10.6667
2 │     2  missing

#### tlast(subj)

Time of last measurable concentration after a dose.

julia> NCA.tlast(df_r1)2×2 DataFrame
Row │ id     tlast
│ Int64  Int64
─────┼──────────────
1 │     1      6
2 │     2      8

#### clast(subj; pred=false)

Concentration corresponding to tlast.

julia> NCA.clast(df_r1)2×2 DataFrame
Row │ id     clast
│ Int64  Float64
─────┼────────────────
1 │     1      0.1
2 │     2      0.1

#### tlag(subj)

Time prior to the first increase in concentration. Mostly relevant for ev dosing.

julia> NCA.tlag(df_r2)2×2 DataFrame
Row │ id     tlag
│ Int64  Int64?
─────┼────────────────
1 │     1  missing
2 │     2        0

#### auc

auc(subj;
auctype=:inf,
method=:linear,
interval=nothing,
normalize=false,
pred=false)

The area under the curve (AUC). This is one of the most important parameters. There are many key important options that can be tailored in the auc function. The defaults are listed in the function signature, but the possible options are listed below:

method    = [:linear, :linuplogdown, :linlog]
auctype   = [:inf, :last]
normalize = [false, true]
pred      = [false, true]

In addition, the interval can be set to a tuple that specified the range in the units of time. e.g. interval =(0,2). If users had passed in timeu into read_nca, then the tuple should be multiplied by the timeu. e.g.

NCA.auc(df1_r, interval = (0,2)) # when no time units passed to read_nca
NCA.auc(df1_r, interval = (0,2) .* timeu) # when no time units passed to read_nca

The code below produces the AUC for all possible scenarios of the auc signature. For brevity, the output is suppressed, but user should be able to run this locally and see all the necessary output.

pops = [df_r1, df_r2, df_r3, df_r4]
methods = [:linear, :linuplogdown,:linlog]
auctypes = [:inf, :last]
normalizes = [false, true]
preds = [false, true]
itrs = Iterators.product(eachindex(pops), methods,auctypes, normalizes, preds)
res = map(itrs) do (popsi, methodsi,auctypesi, normalizesi, predsi)
res = NCA.auc(pops[popsi],
auctype=auctypesi,
method=methodsi,
interval=nothing,
normalize=normalizesi,
pred=predsi)
res[!, :data] .= "df_r" * string(popsi)
res[!,:auctype] .= auctypesi
res[!,:method] .= methodsi
res[!,:normalize] .= normalizesi
res[!,:pred] .= predsi
res
end
aucres = sort(reduce(vcat, res), [:data, :id, :auctype, :method, :normalize, :pred])

#### auctau

auctau(subj;
method=:linear,
interval=nothing,
normalize=false,
pred=false)

The AUC in the dosing interval. This primarily uses the information regarding multiple doses available via ii or if it is a plain multiple dose. This is nothing but an alias for NCA.auc(subj; auctype = :last, interval = (0, NCA.tau(subj))

We can confirm by comparing the result of auctau

julia> NCA.auctau(df_r3)2×2 DataFrame
Row │ id     auctau
│ Int64  Float64
─────┼────────────────
1 │     1  24.3333
2 │     2  13.0

to the result of auc(.., interval(0, NCA.tau(subj)))

julia> NCA.auc(df_r3, auctype=:last, interval=(0,4))2×2 DataFrame
Row │ id     auc0_4
│ Int64  Float64
─────┼────────────────
1 │     1  24.3333
2 │     2  13.0

#### aumc

aumc(subj;
auctype=:inf,
method=:linear,
interval=nothing,
normalize=false,
pred=false)

The area under the first moment of the concentration (AUMC).

#### aumctau

aumctau(subj;
method=:linear,
interval=nothing,
normalize=false,
pred=false)

The AUMC in the dosing interval.

#### vz(subj; pred=false)

Volume of distribution during the terminal phase.

#### cl(subj; pred=false)

Total drug clearance.

#### vss(subj; pred=false)

Apparent volume of distribution at equilibrium for IV bolus doses.

#### fluctuation(nca; usetau=false)

Peak trough fluctuation over one dosing interval at steady state. It is

$100*(C_{maxss} - C_{minss})/C_{avgss}$ for (usetau=false)

$100*(C_{maxss} - C_{tau})/C_{avgss}$ for (usetau=true)

#### accumulationindex(subj)

Theoretical accumulation ratio.

#### auc_extrap_percent(subj; pred=false)

The percentage of AUC infinity due to extrapolation from tlast.

#### auc_back_extrap_percent(subj; pred=false)

The percentage of AUC infinity due to back extrapolation of c0.

#### aumc_extrap_percent(subj; pred=false)

The percentage of AUMC infinity due to extrapolation from tlast.

#### aumc_back_extrap_percent(subj; pred=false)

The percentage of AUMC infinity due to back extrapolation of c0.

#### mrt(subj; auctype=:inf)

Mean residence time from the time of dosing to the time of the last measurable concentration.

#### swing(subj; usetau=false)

Swing. $swing = (C_{maxss}-C_{minss})/C_{minss}$ for (usetau=false)

$swing = (C_{maxss}-C_{tau})/C_{tau}$ for (usetau=true)

### NCA Function List for Urine Analysis

For urine analysis the functions are:

#### n_samples(subj)

The number of measurements that is above the lower limit of quantification.

#### doseamt(subj)

The amount of dose given to each subject.

#### urine_volume(subj)

Collected urine volume.

#### lambdaz(subj)

Terminal elimination rate constant ($λz$).

#### lambdazr2(subj)

Coefficient of determination ($r²$) when calculating $λz$. Note that this quantity must be computed after calculating $λz$.

#### lambdazadjr2(subj)

Adjusted coefficient of determination ($adjr²$) when calculating $λz$. Note that this quantity must be computed after calculating $λz$.

#### lambdazr(subj)

Correlation coefficient ($r$) when calculating $λz$. Note that this quantity must be computed after calculating $λz$.

#### lambdaznpoints(subj)

Number of points that is used in the $λz$ calculation. Note that this quantity must be computed after calculating $λz$.

#### lambdazintercept(subj)

y-intercept in the log-linear scale when calculating $λz$. Note that this quantity must be computed after calculating $λz$.

#### lambdaztimefirst(subj)

The first time point that is used in the $λz$ calculation. Note that this quantity must be computed after calculating $λz$.

#### lambdaztimelast(subj)

The last time point that is used in the $λz$ calculation. Note that this quantity must be computed after calculating $λz$.

Half life.

#### span(subj)

(lambdaztimelast(subj; kwargs...) - lambdaztimefirst(subj) / thalf(subj). Note that this quantity must be computed after calculating $λz$.

#### tlag(subj)

Time prior to the first increase in concentration.

#### tmax_rate(subj)

Midpoint of collection interval associated with the maximum observed excretion rate.

#### max_rate(subj)

Maximum observed excretion rate.

#### rate_last(subj; pred=false)

Last measurable rate.

#### mid_time_last(subj)

Midpoint of collection interval associated with rate_last.

#### amount_recovered(subj)

Cumulative amount eliminated.

#### percent_recovered(subj)

100*amount_recovered/doseamt.

#### aurc

aurc(subj;
auctype=:inf,
method=:linear,
interval=nothing,
normalize=false,
pred=false) 

The area under the urinary excretion rate curve (AURC).

#### aurc_extrap_percent(subj; pred=false)

The percentage of AURC infinity due to extrapolation from tlast`.