Run an nlmixr2 model in an isolated subprocess
Source:R/run_model_in_subprocess.R
run_model_in_subprocess.RdExecutes an nlmixr2 model fitting procedure in a separate background R session using the processx backend. Running the model in an isolated subprocess prevents the main R session from crashing and allows monitoring errors, wall-time limits, and controlled output.
Usage
run_model_in_subprocess(
modi,
dat,
f,
saem.control = NULL,
table.control = NULL,
max_errors = 100,
max_wall_time = 86400,
temp_path = NULL,
cleanup = TRUE,
verbose = TRUE
)Arguments
- modi
Integer. A model index used to generate unique temporary filenames.
- dat
A data frame containing pharmacokinetic data in standard nlmixr2 format for model fitting.
- f
An nlmixr2 model function (e.g., generated by
ppkmodGen(..., return.func = TRUE)).- saem.control
A
saemControl()object providing estimation settings.- table.control
A
tableControl()object controlling table output behavior.- max_errors
Integer. Maximum number of detected error messages before forcibly terminating the subprocess. Default is 100.
- max_wall_time
Numeric (seconds). Maximum allowed real (wall-clock) time for the subprocess before termination. Default is 86400 (24 hours).
- temp_path
Character. Directory where temporary files will be written. If NULL (default), the system temporary directory
tempdir()is used. If a non-NULL path is supplied but does not exist, the function aborts with an error.- cleanup
Logical. Whether to delete all temporary files upon completion. Default is TRUE. If FALSE, generated temporary files are preserved for debugging/troubleshooting.
- verbose
Logical. If TRUE, progress and diagnostic messages are printed during subprocess monitoring. Default is TRUE.
Value
A list with:
- fit.s
The fitted nlmixr2 object, or NULL if the subprocess failed.
- loadError
Logical indicating whether an error occurred (including timeout or crash).
Details
The model fitting is executed in an isolated background R process
(via processx) to prevent the main R session from crashing due to
instabilities in long-running nlmixr2/SAEM estimation routines or poorly
specified models. Output and error streams are monitored in real time, and
the subprocess is automatically terminated if either the error count
(max_errors) or the wall-time limit (max_wall_time) is
exceeded.
Temporary files used to pass data and retrieve results are stored only in
the session-specific temporary directory (tempdir()) and are removed
upon completion, ensuring that no files are created in or left behind in the
user's working directory.
Examples
# \donttest{
# Example: run a simple nlmixr2 model
pheno <- function() {
ini({
tcl <- log(0.008) # typical clearance
tv <- log(0.6) # typical volume
eta.cl + eta.v ~ c(1,
0.01, 1) # interindividual variability
add.err <- 0.1 # residual variability
})
model({
cl <- exp(tcl + eta.cl)
v <- exp(tv + eta.v)
ke <- cl / v
d/dt(A1) = -ke * A1
cp = A1 / v
cp ~ add(add.err)
})
}
run_model_in_subprocess(
modi = 1,
dat = pheno_sd,
f = pheno,
saem.control = nlmixr2est::saemControl(
seed = 1234,
nBurn = 100,
nEm = 100,
logLik = TRUE
)
)
#> $fit.s
#> ── nlmixr² SAEM OBJF by FOCEi approximation ──
#>
#> OBJF AIC BIC Log-likelihood Condition#(Cov) Condition#(Cor)
#> FOCE 696.2748 993.1458 1011.406 -490.5729 5.183607 4.390777
#>
#> ── Time (sec $time): ──
#>
#> setup covariance preprocess configure saem postprocess table
#> elapsed 0.04025946 0.01300355 0.023 0.021 4.617 0.417 0.063
#> compress other
#> elapsed 0.054 1.006737
#>
#> ── Population Parameters ($parFixed or $parFixedDf): ──
#>
#> Est. SE %RSE Back-transformed(95%CI) BSV(CV%) Shrink(SD)%
#> tcl -5.01 0.0768 1.53 0.00669 (0.00575, 0.00777) 52.5 2.65%
#> tv 0.342 0.0551 16.1 1.41 (1.26, 1.57) 42.1 2.01%
#> add.err 2.7 2.7
#>
#> Covariance Type ($covMethod): linFim
#> Correlations in between subject variability (BSV) matrix:
#> cor:eta.v,eta.cl
#> 0.899
#>
#>
#> Full BSV covariance ($omega) or correlation ($omegaR; diagonals=SDs)
#> Distribution stats (mean/skewness/kurtosis/p-value) available in $shrink
#> Censoring ($censInformation): No censoring
#>
#> ── Fit Data (object is a modified tibble): ──
#> # A tibble: 155 × 17
#> ID TIME DV PRED RES IPRED IRES IWRES eta.cl eta.v cp A1
#> <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 2 17.3 17.6 -0.287 18.5 -1.18 -0.436 -0.0305 -0.0495 18.5 24.8
#> 2 1 112. 31 28.1 2.92 29.3 1.69 0.624 -0.0305 -0.0495 29.3 39.3
#> 3 2 2 9.7 10.6 -0.852 11.2 -1.52 -0.563 -0.289 -0.0595 11.2 14.9
#> # ℹ 152 more rows
#> # ℹ 5 more variables: cl <dbl>, v <dbl>, ke <dbl>, tad <dbl>, dosenum <dbl>
#>
#> $loadError
#> [1] FALSE
#>
# }