Example: Conditional covariate (if/else)

This example demonstrates how to implement a piecewise covariate effect using an if / else block in [individual_parameters].

When to use conditional covariates

Use if / else when:

  • The covariate effect is expected to be qualitatively different above and below a threshold (e.g., renal function classification, paediatric vs adult dosing).
  • A continuous power-function covariate is not a good fit and the data support a break-point.
  • You are translating an existing NONMEM model that uses IF (WT.GT.70) THEN ... ENDIF or an nlmixr2 model with if (WT > 70) { }.

Dataset

The dataset must contain the covariate column(s) referenced in the if condition. This example uses WT (the only covariate in the model). The bundled dataset also carries CRCL, but that column is not used by this particular model:

ID,TIME,DV,EVID,AMT,CMT,RATE,MDV,WT,CRCL
1,0,.,1,100,1,0,1,82,95
1,1,4.2,0,.,1,0,0,82,95
1,2,7.8,0,.,1,0,0,82,95
...
2,0,.,1,100,1,0,1,61,72
2,1,3.1,0,.,1,0,0,61,72

Covariate values that change within a subject are supported via EVID=2 rows: the compartment state is unchanged but PK parameters are re-evaluated from the new covariate values at that time point (matching NONMEM’s $PK runs at every record semantic). For time-constant covariates no EVID=2 rows are needed.

Model file

[parameters]
  theta TVCL(4.0, 0.1, 100.0)
  theta TVV1(40.0, 1.0, 500.0)
  theta TVQ(8.0, 0.1, 100.0)
  theta TVV2(80.0, 1.0, 500.0)
  theta TVKA(1.0, 0.01, 10.0)

  omega ETA_CL ~ 0.15
  omega ETA_V1 ~ 0.15
  omega ETA_Q  ~ 0.08
  omega ETA_V2 ~ 0.08
  omega ETA_KA ~ 0.20

  sigma PROP_ERR ~ 0.04

[individual_parameters]
  if (WT > 70) {
    CL = TVCL * exp(ETA_CL) * (WT / 70)^0.75
  } else {
    CL = TVCL * exp(ETA_CL)
  }
  V1 = TVV1 * exp(ETA_V1) * (WT / 70)
  Q  = TVQ  * exp(ETA_Q)
  V2 = TVV2 * exp(ETA_V2)
  KA = TVKA * exp(ETA_KA)

[structural_model]
  pk two_cpt_oral(cl=CL, v1=V1, q=Q, v2=V2, ka=KA)

[error_model]
  DV ~ proportional(PROP_ERR)

[fit_options]
  method     = focei
  maxiter    = 300
  covariance = false   # disabled here because the example dataset is small;
                       # set covariance = true for real analyses

Subjects with WT > 70 kg receive an allometric clearance boost (WT / 70)^0.75; lighter subjects use the typical CL directly. V1 uses a linear WT effect regardless of the CL branch.

Both TVCL * exp(ETA_CL) * (WT/70)^0.75 and TVCL * (WT/70)^0.75 * exp(ETA_CL) are detected correctly as mu-referenced — term order no longer matters.

Syntax rules

  • Both branches must assign the same variable (CL in both arms above).
  • The condition can use any dataset column or previously-computed variable in [individual_parameters].
  • else is optional: if omitted, the variable retains whatever value it had before the if block (useful for additive adjustments).
  • Nested if blocks are supported.

Running

library(ferx)
ex  <- ferx_example("warfarin_if")
fit <- ferx_fit(ex$model, ex$data)
fit

Equivalents in other tools

Tool Syntax
NONMEM IF (WT.GT.70) THEN CL = ... ELSE CL = ... ENDIF
nlmixr2 if (WT > 70) { CL <- ... } else { CL <- ... }
ferx if (WT > 70) { CL = ... } else { CL = ... }

See also