Combining Objects with PKNCAdata() and Defining Intervals

Combine concentration and dose objects using PKNCAdata(), define analysis intervals explicitly, and prepare for full NCA calculation.
Tip

Big idea: NCA is not just concentration plus dose. It is concentration + dose + clearly defined intervals. Intervals encode your study design assumptions.

Learning Objectives

By the end of this lesson, you will be able to:

  • Combine PKNCAconc() and PKNCAdose() objects using PKNCAdata().
  • Define analysis intervals explicitly.
  • Understand common interval types (0–tlast, 0–Inf, 0–tau).
  • Perform structural checks before running pk.nca().

Key Ideas

  • PKNCAdata() links concentration and dose objects.
  • Intervals determine which exposure metrics are calculated.
  • Interval definitions are part of study design — not defaults to ignore.
  • Clear interval specification improves reproducibility and auditability.

Recreate Concentration and Dose Objects

We begin by recreating the objects from the previous lessons.

library(tidyverse)
library(PKNCA)

data(Theoph)

theoph_conc <- as_tibble(Theoph) %>%
  transmute(
    ID   = Subject,
    TIME = Time,
    CONC = conc
  )

theoph_dose <- as_tibble(Theoph) %>%
  distinct(Subject, Dose) %>%
  transmute(
    ID   = Subject,
    TIME = 0,
    DOSE = Dose
  )

conc_obj <- PKNCAconc(CONC ~ TIME | ID, data = theoph_conc)
dose_obj <- PKNCAdose(DOSE ~ TIME | ID, data = theoph_dose)

What Are Intervals?

An interval defines:

  • Start time
  • End time
  • Whether to calculate half-life
  • Whether to extrapolate to infinity

Common interval types:

  • \(AUC_{0-tlast}\)
  • \(AUC_{0-\infty}\)
  • \(AUC_{0-\tau}\) (multiple-dose)

In a single-dose study like Theoph, a typical interval is:

  • Start: 0
  • End: Inf
  • Calculate half-life: Yes

Defining an Interval Data Frame

PKNCA requires an interval specification. We define it explicitly.

intervals_df <- data.frame(
  start = 0,
  end = Inf,
  cmax = TRUE,
  aucinf.obs = TRUE,
  half.life = TRUE
)

intervals_df
  start end cmax aucinf.obs half.life
1     0 Inf TRUE       TRUE      TRUE

This tells PKNCA:

  • Compute Cmax
  • Compute AUC extrapolated to infinity
  • Estimate terminal half-life

Combining with PKNCAdata()

Now combine everything:

nca_data <- PKNCAdata(
  conc_obj,
  dose_obj,
  intervals = intervals_df
)

nca_data
Formula for concentration:
 CONC ~ TIME | ID
Data are dense PK.
With 12 subjects defined in the 'ID' column.
Nominal time column is not specified.

First 6 rows of concentration data:
 ID TIME  CONC exclude volume duration
  1 0.00  0.74    <NA>     NA        0
  1 0.25  2.84    <NA>     NA        0
  1 0.57  6.57    <NA>     NA        0
  1 1.12 10.50    <NA>     NA        0
  1 2.02  9.66    <NA>     NA        0
  1 3.82  8.58    <NA>     NA        0
Formula for dosing:
 DOSE ~ TIME | ID
Nominal time column is not specified.

First 6 rows of dosing data:
 ID TIME DOSE exclude         route duration
  1    0 4.02    <NA> extravascular        0
  2    0 4.40    <NA> extravascular        0
  3    0 4.53    <NA> extravascular        0
  4    0 4.40    <NA> extravascular        0
  5    0 5.86    <NA> extravascular        0
  6    0 4.00    <NA> extravascular        0

With 1 rows of interval specifications.
With imputation: NA
No options are set differently than default.

This object now contains:

  • Concentration structure
  • Dose structure
  • Interval rules

No calculations yet — just complete structural specification.


Structural QC Before Calculation

Before running pk.nca(), confirm:

  1. Number of profiles
  2. Interval definitions
  3. Grouping alignment

Check number of subjects:

theoph_conc %>%
  summarise(n_profiles = n_distinct(ID))
# A tibble: 1 × 1
  n_profiles
       <int>
1         12

Confirm interval structure:

intervals_df
  start end cmax aucinf.obs half.life
1     0 Inf TRUE       TRUE      TRUE

Strategies

  • Always define intervals explicitly.
  • Match intervals to study design.
  • Document interval logic in scripts.
  • Avoid relying on implicit defaults.

Common Mistakes

Warning
  • Using Inf without sufficient terminal sampling.
  • Forgetting to enable half-life estimation.
  • Assuming tau is auto-detected correctly in multiple-dose studies.
  • Treating intervals as cosmetic rather than structural.

Practice Problems

Conceptual

  1. Why should intervals be defined explicitly rather than relying on defaults?
  2. When would \(AUC_{0-\tau}\) be more appropriate than \(AUC_{0-\infty}\)?

Executable

  1. Modify intervals_df to compute only \(AUC_{0-tlast}\) (no extrapolation).
  2. Create an interval that starts at 0 and ends at 8 hours.

1. Explicit intervals:
Explicit definitions improve reproducibility and ensure calculations match study design.

2. AUC0-tau:
Used in steady-state or multiple-dose studies where exposure per dosing interval is relevant.

3. AUC0-tlast only:

intervals_tlast <- data.frame(
  start = 0,
  end = NA,
  aucinf.obs = FALSE,
  half.life = FALSE
)

intervals_tlast
  start end aucinf.obs half.life
1     0  NA      FALSE     FALSE

4. 0 to 8 hours interval:

intervals_0_8 <- data.frame(
  start = 0,
  end = 8,
  cmax = TRUE
)

intervals_0_8
  start end cmax
1     0   8 TRUE

Summary

To prepare for NCA calculation:

  • Build concentration object.
  • Build dose object.
  • Define intervals explicitly.
  • Combine everything using PKNCAdata().

You now have a fully structured NCA specification.


  • Intervals encode design assumptions — treat them carefully.
  • Always align intervals with sampling schedule.
  • Do structural QC before calling pk.nca().
  • Keep interval definitions documented for audit purposes.