Getting Started with lstparsR
Raban Heller
Dominik Selzer
Simeon Rüdesheim
Christiane Dings
Thorsten Lehr
Source:vignettes/getting-started.Rmd
getting-started.RmdOverview
lstparsR reads NONMEM .lst listing
files and extracts parameter estimates into tidy tibbles. It is designed
for population pharmacokinetic and pharmacodynamic (PK/PD) workflows
where many model runs need to be parsed programmatically.
Key design choices:
- Parameter output is returned as tibbles with consistent column names.
- Missing optional quantities (e.g., standard errors when the
covariance step is absent) are
NA. Missing required parameter sections raise errors;fetch_all()catches these, warns, and returnsNULLfor failed elements. - Both VECTOR blocks (THETA) and lower-triangular MATRIX blocks (OMEGA, SIGMA) are handled, including multi-line parameter sets.
Reading a Listing File
Use read_lst_file() to load a .lst file
into an S3 object of class "lst":
path <- system.file("testdata", "full_cov.lst", package = "lstparsR")
lst <- read_lst_file(path)
lst
#> <lst> NONMEM listing file: 1321 lines
summary(lst)
#> <lst> NONMEM listing file
#> Lines : 1321
#> Estimation method: FIRST ORDER CONDITIONAL ESTIMATION WITH INTERACTION
#> Covariance step : TRUEThe lst object is simply a character vector (one element
per line) with class "lst" attached. All
fetch_* functions require this class.
Extracting THETA (Fixed Effects)
fetch_thetas(lst)
#> # A tibble: 12 × 4
#> parameter estimate se rse
#> <chr> <dbl> <dbl> <dbl>
#> 1 TH_1 34.1 3.37e+ 0 9.88e 0
#> 2 TH_2 387000 5.41e+ 7 1.40e 4
#> 3 TH_3 8.05 5.2 e- 1 6.46e 0
#> 4 TH_4 1.78 1.49e- 1 8.37e 0
#> 5 TH_5 0.498 2.78e- 2 5.58e 0
#> 6 TH_6 0.362 4.81e- 1 1.33e 2
#> 7 TH_7 -0.171 1.35e- 1 7.89e 1
#> 8 TH_8 -0.0314 2.69e- 1 8.57e 2
#> 9 TH_9 -0.163 2.78e- 1 1.71e 2
#> 10 TH10 -0.23 1.88e- 1 8.17e 1
#> 11 TH11 0.00539 1.98e- 2 3.67e 2
#> 12 TH12 0.2 1.90e+74 9.50e76Each row corresponds to one THETA parameter. The se and
rse columns contain the standard error and relative
standard error (as a percentage), respectively.
Use the digits argument to round RSE values:
fetch_thetas(lst, digits = 1)
#> # A tibble: 12 × 4
#> parameter estimate se rse
#> <chr> <dbl> <dbl> <dbl>
#> 1 TH_1 34.1 3.37e+ 0 9.9 e 0
#> 2 TH_2 387000 5.41e+ 7 1.40e 4
#> 3 TH_3 8.05 5.2 e- 1 6.5 e 0
#> 4 TH_4 1.78 1.49e- 1 8.4 e 0
#> 5 TH_5 0.498 2.78e- 2 5.6 e 0
#> 6 TH_6 0.362 4.81e- 1 1.33e 2
#> 7 TH_7 -0.171 1.35e- 1 7.89e 1
#> 8 TH_8 -0.0314 2.69e- 1 8.57e 2
#> 9 TH_9 -0.163 2.78e- 1 1.71e 2
#> 10 TH10 -0.23 1.88e- 1 8.17e 1
#> 11 TH11 0.00539 1.98e- 2 3.67e 2
#> 12 TH12 0.2 1.90e+74 9.50e76Extracting OMEGA (Random Effects)
fetch_etas() extracts the diagonal of the OMEGA
covariance matrix, plus ETA shrinkage when reported:
fetch_etas(lst)
#> # A tibble: 7 × 5
#> parameter estimate se rse shrinkage
#> <chr> <dbl> <dbl> <dbl> <dbl>
#> 1 ETA1 0.2 3.89e- 2 1.94e 1 5.08
#> 2 ETA2 0.255 4.63e- 2 1.82e 1 1.62
#> 3 ETA3 0.1 2 e+73 2 e76 100
#> 4 ETA4 0.1 1.99e+73 1.99e76 100
#> 5 ETA5 0.00001 6.85e+68 6.85e75 97.6
#> 6 ETA6 0.00001 NA NA 99.0
#> 7 ETA7 0.00001 NA NA 97.0Shrinkage values can be rounded separately:
fetch_etas(lst, digits = 1, shk_digits = 1)
#> # A tibble: 7 × 5
#> parameter estimate se rse shrinkage
#> <chr> <dbl> <dbl> <dbl> <dbl>
#> 1 ETA1 0.2 3.89e- 2 1.94e 1 5.1
#> 2 ETA2 0.255 4.63e- 2 1.82e 1 1.6
#> 3 ETA3 0.1 2 e+73 2 e76 100
#> 4 ETA4 0.1 1.99e+73 1.99e76 100
#> 5 ETA5 0.00001 6.85e+68 6.85e75 97.6
#> 6 ETA6 0.00001 NA NA 99
#> 7 ETA7 0.00001 NA NA 97Extracting SIGMA (Residual Error)
fetch_sigmas(lst)
#> # A tibble: 2 × 4
#> parameter estimate se rse
#> <chr> <dbl> <dbl> <dbl>
#> 1 EPS1 0.0769 0.00434 5.64
#> 2 EPS2 0.123 0.199 162.Objective Function Value
fetch_ofv(lst)
#> [1] 8986.318For failed runs, fetch_ofv() falls back to the workflow
footer (OFV = ...) if the standard #OBJV: line
is absent.
Condition Number
The condition number is computed as the ratio of the largest to smallest eigenvalue of the correlation matrix of parameter estimates. Values above 1000 suggest numerical instability:
fetch_condn(lst)
#> [1] 23.30882All at Once
fetch_all() runs every parser in a single call.
Individual parser failures are caught and returned as NULL
with a warning, so a single problematic section does not abort the
entire extraction:
result <- fetch_all(lst)
names(result)
#> [1] "thetas" "etas" "sigmas" "ofv" "condn"
result$thetas
#> # A tibble: 12 × 4
#> parameter estimate se rse
#> <chr> <dbl> <dbl> <dbl>
#> 1 TH_1 34.1 3.37e+ 0 9.88e 0
#> 2 TH_2 387000 5.41e+ 7 1.40e 4
#> 3 TH_3 8.05 5.2 e- 1 6.46e 0
#> 4 TH_4 1.78 1.49e- 1 8.37e 0
#> 5 TH_5 0.498 2.78e- 2 5.58e 0
#> 6 TH_6 0.362 4.81e- 1 1.33e 2
#> 7 TH_7 -0.171 1.35e- 1 7.89e 1
#> 8 TH_8 -0.0314 2.69e- 1 8.57e 2
#> 9 TH_9 -0.163 2.78e- 1 1.71e 2
#> 10 TH10 -0.23 1.88e- 1 8.17e 1
#> 11 TH11 0.00539 1.98e- 2 3.67e 2
#> 12 TH12 0.2 1.90e+74 9.50e76
result$ofv
#> [1] 8986.318
result$condn
#> [1] 23.30882Runs Without a Covariance Step
When NONMEM did not run or complete a covariance step, SE, RSE, and
condition number are returned as NA:
path2 <- system.file("testdata", "theta_without_cov.lst", package = "lstparsR")
lst2 <- read_lst_file(path2)
fetch_thetas(lst2)
#> # A tibble: 12 × 4
#> parameter estimate se rse
#> <chr> <dbl> <dbl> <dbl>
#> 1 TH_1 34.1 NA NA
#> 2 TH_2 387000 NA NA
#> 3 TH_3 8.05 NA NA
#> 4 TH_4 1.78 NA NA
#> 5 TH_5 0.498 NA NA
#> 6 TH_6 0.362 NA NA
#> 7 TH_7 -0.171 NA NA
#> 8 TH_8 -0.0314 NA NA
#> 9 TH_9 -0.163 NA NA
#> 10 TH10 -0.23 NA NA
#> 11 TH11 0.00539 NA NA
#> 12 TH12 0.2 NA NA
fetch_condn(lst2)
#> [1] NABatch Processing
A common pattern is to parse many .lst files at
once:
library(purrr)
lst_files <- list.files("models/", pattern = "\\.lst$", full.names = TRUE)
results <- map(lst_files, \(f) {
lst <- read_lst_file(f)
fetch_all(lst)
})
# Combine all THETA tables
all_thetas <- map_dfr(results, "thetas", .id = "run")Estimation Headers and Output Layouts
lstparsR recognizes the following NONMEM estimation method headers:
- First Order (FO)
- First Order Conditional Estimation (FOCE)
- First Order Conditional Estimation with Interaction (FOCE-I)
- Stochastic Approximation Expectation-Maximization (SAEM)
- Importance Sampling (IMP)
- Importance Sampling Assisted by Mode A Posteriori (IMPMAP)
- Markov Chain Monte Carlo Bayesian Analysis
Numerical regression tests cover FOCE-I listings and controlled edge cases; FO listings have additional execution coverage. Recognizing a method header does not validate every layout or posterior summary from that method. The parsers expect the fixed-format result sections shown in the examples. Compare results with the original listing for unfamiliar layouts. Parsing does not validate the scientific model or its estimates.
Interactive Exploration
For interactive use, launch the built-in Shiny application:
lstparsR::run_app()This opens a browser-based interface where you can upload
.lst files, view parsed results in tables, and download
them as CSV or RDS.