The [derived] block adds computed columns to sdtab after the fit. The [output] block echoes individual PK parameters and covariates into sdtab that would not be there otherwise. Neither block affects estimation — they are pure post-processing.
Model
library (ferx)
ex <- ferx_example ("warfarin_derived" )
ferx_model_show (ex$ model)
# model: warfarin_derived.ferx
# One-compartment oral PK model (warfarin) -- [derived] and [output] demo
[parameters]
theta TVCL(0.2, 0.001, 10.0)
theta TVV(10.0, 0.1, 500.0)
theta TVKA(1.5, 0.01, 50.0)
omega ETA_CL ~ 0.09
omega ETA_V ~ 0.04
omega ETA_KA ~ 0.30
sigma PROP_ERR ~ 0.02 (sd)
[individual_parameters]
CL = TVCL * exp(ETA_CL)
V = TVV * exp(ETA_V)
KA = TVKA * exp(ETA_KA)
[structural_model]
pk one_cpt_oral(cl=CL, v=V, ka=KA)
[error_model]
DV ~ proportional(PROP_ERR)
[derived]
# Per-row: elimination rate and half-life
KE = CL / V
T_HALF = 0.6931472 / KE
# Which dosing day (tau = 24 h)
DAY = floor(TAFD / 24) + 1
TAU_TIME = TAFD mod 24
# Subject-level aggregates (one scalar per subject, repeated across rows)
CMAX = max(IPRED)
TMAX = tmax(IPRED)
# 1e-10 absorbs floating-point residuals when TAD is mathematically 0
CTROUGH = min(IPRED, TAD < 1e-10)
CMAX_D1 = max(IPRED, TAFD < 24)
CMAX_D14 = max(IPRED, TAFD >= 312 && TAFD < 336)
# AUC over first 72 h (fine internal grid, 500 steps)
AUC_0_72 = integral(IPRED, from=0, to=72)
# Periodic AUC: one value per 24-h dosing window
AUC_TAU = integral(IPRED, window=24, anchor=0, step=0.1)
# DV-based AUC (observation times only -- no interpolation)
AUC_DV_72 = integral(DV, from=0, to=72)
[output]
# Echo individual PK parameters (ETAs already automatic)
CL V KA
[fit_options]
method = foce
maxiter = 300
covariance = true
The model adds twelve derived columns covering all three computation kinds:
KE, T_HALF, DAY, TAU_TIME
Per-row
Evaluated at each observation time
CMAX, TMAX, CTROUGH, CMAX_D1, CMAX_D14
Aggregate
One value per subject (last two NaN for single-dose data)
AUC_0_72, AUC_TAU, AUC_DV_72
Integral
Trapezoidal / periodic / DV-based AUC
[output] then adds CL, V, and KA (individual EBE parameter values).
Fit
fit <- ferx_fit (ex$ model, ex$ data, verbose = FALSE )
print (fit)
============================================================
NONLINEAR MIXED EFFECTS MODEL ESTIMATION
============================================================
Model: warfarin_derived Dataset: warfarin
Method: FOCE | Gradient: ANALYTIC (DUAL2) | Subjects: 10 | Obs: 110
STATUS: CONVERGED 102 iterations 1.5s
OFV: -280.3640 AIC: -266.3640 BIC: -247.4606
MODEL STRUCTURE (auto-derived)
------------------------------------------------------------
Structural: 1-cpt oral (TVCL, TVV, TVKA)
IIV: ETA_CL, ETA_V, ETA_KA
IOV: none
Residual: proportional
THETA
------------------------------------------------------------
Parameter Estimate SE %RSE
----------------------------------------------------
TVCL 0.132970 0.006628 5.0
TVV 7.730695 0.234062 3.0
TVKA 0.725187 0.125303 17.3
OMEGA (between-subject variability)
------------------------------------------------------------
ETA_CL [log-normal] = 0.028585 CV% = 17.0 SE = 0.012790
ETA_V [log-normal] = 0.009575 CV% = 9.8 SE = 0.004294
ETA_KA [log-normal] = 0.348959 CV% = 64.6 SE = 0.160968
SIGMA (residual error)
------------------------------------------------------------
PROP_ERR [proportional] = 0.010749 (var = 0.000116, CV% = 1.1) SE = 0.000942 [initial specified as SD]
SHRINKAGE
------------------------------------------------------------
ETA_CL: 0.0% ETA_V: 0.1% ETA_KA: 0.2% EPS: 16.1%
DIAGNOSTICS
------------------------------------------------------------
Covariance: computed Cond: 2.7 DW: 2.61 [negative autocorrelation] IWRES lag-1 r: -0.365
RUN INFO
------------------------------------------------------------
Gradient (requested): auto (used: analytic (Dual2))
ferx v0.1.6 (core v0.1.6)
SETTINGS (model file / call-time override)
------------------------------------------------------------
method foce [model only]
maxiter 300 [model only]
covariance true [model only]
------------------------------------------------------------
1 warning -- call ferx_warnings(fit) for details
============================================================
sdtab columns
[1] "ID" "TIME" "DV" "PRED" "IPRED" "CWRES"
[7] "IWRES" "EBE_OFV" "N_OBS" "TAFD" "TAD" "CL"
[13] "V" "KA" "KE" "T_HALF" "DAY" "TAU_TIME"
[19] "CMAX" "TMAX" "CTROUGH" "CMAX_D1" "CMAX_D14" "AUC_0_72"
[25] "AUC_TAU" "AUC_DV_72"
Per-row columns
KE and T_HALF depend only on the subject’s EBE CL/V, so they are constant per subject but appear on every row. DAY increments with each 24-h window.
head (fit$ sdtab[, c ("ID" , "TIME" , "TAFD" , "KE" , "T_HALF" , "DAY" )], 12 )
ID TIME TAFD KE T_HALF DAY
1 1 0.5 0.5 0.01655816 41.86136 1
2 1 1.0 1.0 0.01655816 41.86136 1
3 1 2.0 2.0 0.01655816 41.86136 1
4 1 4.0 4.0 0.01655816 41.86136 1
5 1 8.0 8.0 0.01655816 41.86136 1
6 1 12.0 12.0 0.01655816 41.86136 1
7 1 24.0 24.0 0.01655816 41.86136 2
8 1 48.0 48.0 0.01655816 41.86136 3
9 1 72.0 72.0 0.01655816 41.86136 4
10 1 96.0 96.0 0.01655816 41.86136 5
11 1 120.0 120.0 0.01655816 41.86136 6
12 2 0.5 0.5 0.01860709 37.25177 1
Aggregate columns
CMAX, TMAX, and AUC_0_72 are the same on every row of a subject:
unique (fit$ sdtab[, c ("ID" , "CMAX" , "TMAX" , "AUC_0_72" )])
ID CMAX TMAX AUC_0_72
1 1 11.38329 4 510.6520
12 2 12.10572 8 544.1912
23 3 11.01643 4 514.5164
34 4 13.56179 8 594.6227
45 5 13.82101 4 637.5880
56 6 11.70240 2 521.3665
67 7 10.32414 8 441.9933
78 8 11.77892 4 467.5516
89 9 11.04441 4 563.9460
100 10 11.09372 8 533.1617
Filtered aggregates — CMAX_D1 vs CMAX
CMAX_D1 = max(IPRED, TAFD < 24) restricts the maximum to day-1 observations only. Comparing it against the overall CMAX shows how the peak shifts as the drug distributes:
unique (fit$ sdtab[, c ("ID" , "CMAX" , "CMAX_D1" , "TMAX" )])
ID CMAX CMAX_D1 TMAX
1 1 11.38329 11.38329 4
12 2 12.10572 12.10572 8
23 3 11.01643 11.01643 4
34 4 13.56179 13.56179 8
45 5 13.82101 13.82101 4
56 6 11.70240 11.70240 2
67 7 10.32414 10.32414 8
78 8 11.77892 11.77892 4
89 9 11.04441 11.04441 4
100 10 11.09372 11.09372 8
The model also declares CTROUGH = min(IPRED, TAD < 1e-10) to capture the pre-dose trough, and CMAX_D14 = max(IPRED, TAFD >= 312 && TAFD < 336) for the steady-state day-14 peak. Both are NaN here because the warfarin dataset is a single-dose study (no repeated doses, data ends at 120 h) — TAD never resets to ≈ 0 at an observation time, and no observations fall in the 312–336 h window. These columns are designed for multi-dose designs . For a working trough example see Example: ADDL/multiple-dose .
Periodic AUC (AUC_TAU)
AUC_TAU = integral(IPRED, window=24, anchor=0, step=0.1) produces one value per 24-h dosing window. It changes across windows as the concentration profile evolves:
fit$ sdtab[fit$ sdtab$ ID == fit$ sdtab$ ID[1 ],
c ("TIME" , "TAFD" , "AUC_TAU" )]
TIME TAFD AUC_TAU
1 0.5 0.5 233.55469
2 1.0 1.0 233.55469
3 2.0 2.0 233.55469
4 4.0 4.0 233.55469
5 8.0 8.0 233.55469
6 12.0 12.0 233.55469
7 24.0 24.0 165.76633
8 48.0 48.0 111.40623
9 72.0 72.0 74.87255
10 96.0 96.0 50.31944
11 120.0 120.0 40.41758
DV-based AUC (AUC_DV_72)
AUC_DV_72 = integral(DV, from=0, to=72) uses the observed values at each observation time rather than IPRED. The step= argument is ignored for DV-based integrals (no interpolation between observations):
unique (fit$ sdtab[, c ("ID" , "AUC_0_72" , "AUC_DV_72" )])
ID AUC_0_72 AUC_DV_72
1 1 510.6520 506.8519
12 2 544.1912 540.0808
23 3 514.5164 510.2423
34 4 594.6227 593.2185
45 5 637.5880 632.7343
56 6 521.3665 516.7186
67 7 441.9933 440.5478
78 8 467.5516 464.2751
89 9 563.9460 563.1022
100 10 533.1617 530.3337
[output] — individual parameter columns
CL, V, and KA appear in sdtab because of the [output] block. Without it, only the mandatory minimum columns plus [derived] names would be present:
unique (fit$ sdtab[, c ("ID" , "CL" , "V" , "KA" )])
ID CL V KA
1 1 0.1367378 8.258032 1.1738301
12 2 0.1350286 7.256836 0.5366661
23 3 0.1297238 8.467318 0.9441843
34 4 0.1291865 6.258011 0.3906890
45 5 0.1052014 6.846145 1.3118066
56 6 0.1315967 8.294638 2.8192265
67 7 0.1776121 8.230884 0.4165787
78 8 0.1738693 7.593123 0.7786906
89 9 0.1022804 8.490377 0.8951078
100 10 0.1251060 8.035877 0.4909804