# Inter-Occasion Variation (IOV)

Just as PK parameters can vary from one individual to the next, they can also vary within an individual over a period of time. Clearances and volumes, for example, can often vary from day-to-day, particularly where inflammation plays a role but even in healthy volunteers. Absorption parameters can also vary substantially with each dosing occasion, sometimes to the extent that IOV is even greater than ISV. As a result, when drugs are administered on multiple occasions it may be important to model this variation, too [KarlssonSheiner1993].

## Data Synthesis with IOV

Note

See the One Compartment Model with Absorption and Inter-occasion Variance f[CL_isv]=0.2 and One Compartment Model with Absorption and Inter-occasion Variance f[CL_isv]=0.5 for the Tut Script used to generate results in this section.

First, we generate some new data with both ISV and IOV by making more changes to the LEVEL_PARAMS section of the script:

1. move values that vary between occasions (just the time points `t[RESET]`, `t[DOSE]` and `t[OBS]`, unless the dose amount, `c[AMT]` varies with occasion) from the INDIV level into a new level, OCCASION.
2. add to the OCCASION level an occasion-specific covariate, `c[OCC]`, that indicates the occasion, and an occasion-specific random effect, `r[CL_iov]`, that is responsible for inter-occasion variation in the model parameter CL.
3. add to the GLOBAL level a population-specific fixed effect, `f[CL_iov]`, that specifies the variance (i.e. the spread) of the inter-occasional random effects, `r[CL_iov]`.

    LEVEL_PARAMS:
        GLOBAL:
            params: |
                f[KA] = 0.3
                f[CL] = 3
                f[V] = 20
                f[PNOISE_STD] = 0.1
                f[ANOISE_STD] = 0.05
                f[CL_isv] = 0.2
                # new: true inter-occasion variability
                f[CL_iov] = 0.1
            split_field: None
            split_dict: {}
        INDIV:
            params: |
                # new: 10 subjects in this population
                c[ID] = sequential(10)
                c[AMT] = 100.0
                r[CL_isv] ~ norm(0, f[CL_isv])
            split_field: ID
            split_dict: "*"
        OCCASION:
            params: |
                # new: 3 occasions per individual
                c[OCC] = sequential(3)
                t[RESET] = 0.0
                t[DOSE] = 1.0
                t[OBS] ~ unif(1.0, 50.0; 4)
                # new: inter-occasion variability
                r[CL_iov] ~ norm(0, f[CL_iov])
            split_field: OCC
            split_dict: "*"

(Here we have also reduced the population to ten individuals with three occasions each in order to maintain 30 time courses.)

Note

Adding the OCCASION level below the INDIV level tells PoPy that there are multiple occasions for an individual, much as adding INDIV below GLOBAL says that there are multiple subjects in the population. Every occasion therefore inherits the parameters defined in the levels above. (See LEVEL_PARAMS.)

The IOV random effect is then added to its ISV sibling in the MODEL_PARAMS section of the script:

    MODEL_PARAMS: |
        m[KA] = f[KA]
        # log-normally distributed ISV and IOV
        m[CL] = f[CL]*exp(r[CL_isv] + r[CL_iov])
        m[V] = f[V]
        m[PNOISE_STD] = f[PNOISE_STD]
        m[ANOISE_STD] = f[ANOISE_STD]

The remaining sections (e.g. DERIVATIVES and PREDICTIONS) remain the same.

As with ISV, this added variation changes the shape of the predicted curves over the set of individuals in the population (Table 22). Depending on the magnitude of the variances, the set of curves may overlap such that it is difficult to separate the individuals or they may form tight clusters. (The overlap will also increase with bigger populations.)

Table 22 Population graphs with increasing ISV: (left) CL_isv=0.2, CL_iov=0.1; (right) CL_isv=0.5, CL_iov=0.01

## Naïve IOV Fit

Note

See One Compartment Model with Absorption and no inter-occasion Variance f[CL_iov]=0 for the Tut Script used to generate results in this section.

As with ISV, we can investigate the effect of excluding IOV from a fit to data where IOV exists by fixing the `f[CL_iov]` variance to zero.

    LEVEL_PARAMS:
        GLOBAL:
            params: |
                f[KA] ~ unif(0.01, 1) 0.5
                f[CL] ~ unif(0.01, 10) 1
                f[V] ~ unif (0.01, 100) 15
                f[PNOISE_STD] ~ unif(0.001, 1) 0.2
                f[ANOISE_STD] ~ unif(0.001, 1) 0.2
                f[CL_isv] ~ unif(0.001, 10) 0.01
                # new: assumed zero inter-occasion variability
                f[CL_iov] = 0
            split_field: None
            split_dict: {}
        INDIV:
            params: |
                r[CL_isv] ~ norm(0, f[CL_isv])
            split_field: ID
            split_dict: "*"
        OCCASION:
            params: |
                # new: inter-occasion variability
                r[CL_iov] ~ norm(0, f[CL_iov])
            split_field: OCC
            split_dict: "*"

Again, although the population parameters are close to their “true” values, the noise parameters and the ISV are all bigger than they should be in order to capture the IOV that has not been modelled

    f[KA] = 1
    f[CL] = 2.1462
    f[V] = 22.086
    f[PNOISE_STD] = 0.46359
    f[ANOISE_STD] = 0.061732
    f[CL_isv] = 4.2967
    f[CL_iov] = 0

and we use the resulting objective function value,

    -163.411429465

as a reference.

## Mixed Effect IOV Fit

Note

See One Compartment Model with Absorption and Inter-occasion Variance f[CL_isv]=0.2 for the Tut Script used to generate results in this section.

Adding IOV to the model by making `f[CL_iov]` a free parameter

    LEVEL_PARAMS:
        GLOBAL:
            params: |
                f[KA] ~ unif(0.01, 1) 0.5
                f[CL] ~ unif(0.01, 10) 1
                f[V] ~ unif (0.01, 100) 15
                f[PNOISE_STD] ~ unif(0.001, 1) 0.2
                f[ANOISE_STD] ~ unif(0.001, 1) 0.2
                f[CL_isv] ~ unif(0.001, 10) 0.01
                # new: estimated inter-occasion variability
                f[CL_iov] ~ unif(0.001, 10) 0.01
            split_field: None
            split_dict: {}
        INDIV:
            params: |
                r[CL_isv] ~ norm(0, f[CL_isv])
            split_field: ID
            split_dict: "*"
        OCCASION:
            params: |
                # new: inter-occasion variability
                r[CL_iov] ~ norm(0, f[CL_iov])
            split_field: OCC
            split_dict: "*"

results in population parameters that are again close to their “true” values, this time including the variance parameters. This reflects the intuition that a correctly defined model requires less variance to capture the observed deviations from the population estimates.

    f[KA] = 1
    f[CL] = 2.2203
    f[V] = 20.724
    f[PNOISE_STD] = 0.21306
    f[ANOISE_STD] = 0.052026
    f[CL_isv] = 0.072757
    f[CL_iov] = 0.1003

As with the ISV example, the final objective function value,

    -276.234851705

is also significantly lower, indicating a better fit of the model to the observed concentrations.