| Title: | Stepwise Covariate Modeling for 'nlmixr2' Models |
| Version: | 0.4 |
| Description: | Stepwise covariate modeling (SCM) for nonlinear mixed-effects models fitted with 'nlmixr2'. Forward inclusion and backward elimination are driven by likelihood-ratio tests, and the covariate terms are generated inside the model body, so continuous covariates are centered and categorical covariates expanded into indicator columns without editing the model by hand. Candidate fits can be cached and resumed, fitted in parallel, and reviewed through per-step and all-candidate summary tables. The approach follows Jonsson and Karlsson (1998) <doi:10.1023/A:1011970125687>, and the implementation in 'Perl-speaks-NONMEM' described by Lindbom, Ribbing and Jonsson (2004) <doi:10.1016/j.cmpb.2003.11.003>. |
| Depends: | R (≥ 4.1) |
| License: | GPL (≥ 3) |
| URL: | https://github.com/nlmixr2/nlmixr2scm |
| BugReports: | https://github.com/nlmixr2/nlmixr2scm/issues |
| Imports: | checkmate, cli (≥ 3.4.0), data.table, lotri, nlme, nlmixr2est (≥ 7.0.0), nlmixr2utils (≥ 0.3), rxode2 (≥ 5.0.0), stats, tools, utils |
| Suggests: | future, knitr, nlmixr2data, pkgload, rmarkdown, testthat (≥ 3.0.0), withr |
| VignetteBuilder: | knitr |
| Config/testthat/edition: | 3 |
| Encoding: | UTF-8 |
| Config/roxygen2/version: | 8.1.0 |
| NeedsCompilation: | no |
| Packaged: | 2026-09-14 09:38:51 UTC; justin |
| Author: | Justin Wilkins |
| Maintainer: | Justin Wilkins <justin.wilkins@occams.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-09-24 13:30:14 UTC |
nlmixr2scm package
Description
Stepwise covariate modeling tools for nlmixr2 fits.
Author(s)
Maintainer: Justin Wilkins justin.wilkins@occams.com (ORCID) [copyright holder]
Authors:
Justin Wilkins justin.wilkins@occams.com (ORCID) [copyright holder]
Matthew Fidler matthew.fidler@gmail.com (ORCID)
Yaping Liu ypliu@umich.edu (ORCID)
Bill Denney wdenney@humanpredictions.com (ORCID)
Vipul Mann vm2583@columbia.edu
Vishal Sarsani vsarsani@umass.edu (ORCID)
Other contributors:
Christian Bartels christian.bartels@novartis.com [contributor]
See Also
Useful links:
Stepwise Covariate Model-selection (SCM) method
Description
Stepwise Covariate Model-selection (SCM) method
Usage
runSCM(
fit,
varsVec = NULL,
covarsVec = NULL,
pVal = list(fwd = 0.05, bck = 0.01),
catvarsVec = NULL,
pairsVec = NULL,
shapes = "power",
customShapes = NULL,
centers = NULL,
inits = list(),
missingToken = NA,
includedRelations = NULL,
data = NULL,
catCutoff = 0.05,
outputDir = NULL,
saveModels = TRUE,
verbose = FALSE,
control = NULL,
print = 100,
searchType = c("scm", "forward", "backward"),
restart = FALSE,
workers = NULL,
confirm = TRUE,
profileInit = FALSE,
profileInitOnStall = TRUE,
stallTol = 0,
maxRetries = 3L,
maxDeltaOFV = Inf,
retryPerturbSD = 0.5,
retrySmallInit = 0.01,
retryOFVTolerance = NULL,
retryFailOnExhaustion = FALSE,
rxThreads = NULL
)
Arguments
fit |
an nlmixr2 'fit' object |
varsVec |
character vector of PK parameters to which covariates may be
added (e.g. |
covarsVec |
character vector of continuous covariate names to test.
Ignored when |
pVal |
a named list with names |
catvarsVec |
character vector of categorical covariate names. Dummy
columns are created internally and appended to |
pairsVec |
optional data frame with columns |
shapes |
character vector of shape names to test for each continuous
covariate-parameter pair. Built-in shapes are |
customShapes |
named list of additional shape builder functions of the
form |
centers |
optional named numeric vector of fixed reference (centering)
values for continuous covariates, e.g. |
inits |
named list mapping shape names to initial theta estimates (and
optionally bounds) for the covariate parameter. Each entry may be either
a scalar estimate (e.g. |
missingToken |
sentinel value used to identify missing covariate
observations in addition to |
includedRelations |
optional specification of covariate-parameter
relationships that must be present in the model at the start of backward
elimination (analogous to PsN's |
data |
data frame containing all subjects and columns required by the
search (covariates, dose/observation records, etc.). When |
catCutoff |
minimum proportion of subjects that must belong to a
non-reference level for it to be tested. Levels below this threshold are
lumped with the reference and excluded from the candidate set. Applied
per unique subject (not per observation row). Default |
outputDir |
character; path of the subdirectory used to store all
fitted model |
saveModels |
logical; if |
verbose |
logical; if |
control |
optional control object (e.g. |
print |
integer; how often (in iterations) the optimiser prints
progress for each candidate model fit. Default |
searchType |
one of |
restart |
logical; if |
workers |
integer or |
confirm |
logical; if |
profileInit |
logical; if |
profileInitOnStall |
logical; if |
stallTol |
numeric; OFV-improvement threshold below which a forward
candidate is considered stalled and eligible for the profile rescue.
Default |
maxRetries |
integer; maximum number of retry attempts per candidate
when the OFV is deemed unrealistic. Default |
maxDeltaOFV |
numeric; absolute ceiling on plausible OFV change. A
candidate whose |
retryPerturbSD |
numeric; standard deviation of the log-normal
perturbation applied to |
retrySmallInit |
numeric; covariate theta init used on even-numbered
retries as a near-zero safe-harbour. Default |
retryOFVTolerance |
numeric or |
retryFailOnExhaustion |
logical; when |
rxThreads |
integer, |
Value
A list with elements summaryTable (combined forward and
backward results), resFwd (list of final fit and step table from
forward search), and resBck (same for backward search).
Author(s)
Vipul Mann, Matthew Fidler, Vishal Sarsani, Justin Wilkins
Examples
# Fitting the base model and running even a one-pair search takes longer
# than a few seconds, so this example is wrapped in \donttest{}.
one.cmt <- function() {
ini({
tka <- 0.45
label("Ka")
tcl <- log(c(0, 2.7, 100))
label("Cl")
tv <- 3.45
label("V")
eta.ka ~ 0.6
eta.cl ~ 0.3
eta.v ~ 0.1
add.sd <- 0.7
})
model({
ka <- exp(tka + eta.ka)
cl <- exp(tcl + eta.cl)
v <- exp(tv + eta.v)
linCmt() ~ add(add.sd)
})
}
fit <- nlmixr2est::nlmixr2(
one.cmt, nlmixr2data::theo_sd,
est = "focei", control = nlmixr2est::foceiControl(print = 0)
)
# Test one parameter-covariate pair. saveModels = FALSE keeps the search
# from writing anything to disk.
res <- runSCM(fit,
pairsVec = list(list(var = "cl", covar = "WT", shapes = "power")),
searchType = "forward",
saveModels = FALSE,
confirm = FALSE,
print = 0,
workers = 1L,
rxThreads = 2L
)
res$summaryTable