Residual-error model search
Description
Runs a residual-error search - Pharmpy’s ruvsearch - over a model’s [error_model] block. Each iteration adds one residual-error feature to the model the last iteration kept, fits every candidate, and accepts the largest improvement the likelihood-ratio test calls significant at p_value. Up to max_iter features are stacked this way.
Usage
ferx_ruvsearch(
model = NULL,
data = NULL,
config = NULL,
groups = NULL,
p_value = NULL,
skip = NULL,
max_iter = NULL,
cwres_prescreen = NULL,
threads = NULL,
retries = NULL,
directory = NULL,
resume = FALSE,
progress = interactive()
)
# S3 method for ferx_ruvsearch
print(x, digits = 4, ...)
# S3 method for ferx_ruvsearch
summary(object, digits = 4, ...)Arguments
model: Path to a.ferxmodel, or aferx_modelobject. Omit whenconfigis given.data: Path to the dataset. Defaults to the model’s[data]block. Names the dataset the search runs on, so likemodelit cannot be given besideconfig- the file’s owndatakey says which dataset that file searches.config: Path to a.ferxsearchfile. Mutually exclusive with the arguments that state the search.groups: Time-after-dose bins the time-varying candidates cut at:groups - 1candidates, at thei / groupsquantiles.NULLkeeps the engine default (4).p_value: The likelihood-ratio level a candidate must reach.NULLkeeps the engine default (0.001).skip: Families never tested, any of"IIV_on_RUV","power","combined","time_varying".NULLtests them all.max_iter: Iterations, 1 to 3 as in Pharmpy.NULLkeeps the engine default (3).cwres_prescreen: Screen the candidates on the parent’s CWRES first and refit only the winner - Pharmpy’s own path, and much cheaper than fitting every candidate to the data.NULLkeeps the engine default (FALSE: every candidate is fitted).threads: Total worker threads.NULLlets the runner choose.retries: Perturbed restarts per candidate on top of the exact one.NULLkeeps the engine default.directory: Where the per-iteration journals,steps.csv,models/<id>.ferxandfinal.ferxare written.NULLkeeps the run in memory, which also means it cannot be resumed.resume: Reuse the fits already journalled indirectory.progress: Print the engine’s iteration progress to the console.x: Aferx_ruvsearchobject.digits: Significant digits for the printed tables....: Ignored.object: Aferx_ruvsearchobject.
Details
There is no search space to state: the candidates are the four families Pharmpy tests, and skip is what narrows them.
IIV_on_RUV: A log-normal per-subject scale on the residual SD (ETA_RUV). Needs an estimation method with eta-epsilon interaction (focei,imp,impmap,saem); on afocemodel it is not tested, and the run says so in$notes.power: The proportional loading raised to an estimated exponent,power(sigma, P).combined: An additive component beside the proportional one.time_varying: Every sigma scaled by a theta for records below a time-after-dose cutoff -groups - 1candidates, at thei / groupsquantiles of time after dose.
power and combined are tested together or not at all, as in Pharmpy, and accepting one of them retires both. The search always starts from a plain proportional error model: when the input is not one, its proportional counterpart is fitted first and becomes the parent of iteration one (base_model_id says which). The final comparison then checks the accepted stack against the input as well, so a search can return the model it started from. A candidate has to pass the strictness gate before it can be accepted, and the step table always carries the termination status and the gate verdict beside the p-value - a candidate that stalled at its initial estimates carries a dOFV that says nothing about the error model it was testing.
Two entry forms
Pass either config - a .ferxsearch file, which is the reproducible artifact - or the inline arguments. The inline form is rendered into the same configuration and handed to the engine’s own loader, so the two cannot disagree. The run arguments (threads, retries, resume, directory, progress) say how to run a search rather than what to search, and are available to both forms. A [space] section, or a [rank] asking for a BIC or a cutoff, is refused by name when the file is read: ruvsearch selects on the likelihood-ratio test at p_value, not on a ranking criterion.
Seealso
[ferx_search_config](ferx_search_config.qmd), [ferx_search_results](ferx_search_results.qmd), [ferx_covsearch](ferx_covsearch.qmd), [ferx_modelsearch](ferx_modelsearch.qmd)Other search: [ferx_allometry](ferx_allometry.qmd), [ferx_amd](ferx_amd.qmd), [ferx_amd_plan](ferx_amd_plan.qmd), [ferx_covsearch](ferx_covsearch.qmd), [ferx_globalsearch](ferx_globalsearch.qmd), [ferx_iivsearch](ferx_iivsearch.qmd), [ferx_iovsearch](ferx_iovsearch.qmd), [ferx_modelsearch](ferx_modelsearch.qmd), [ferx_search_config](ferx_search_config.qmd), [ferx_search_coverage](ferx_search_coverage.qmd), [ferx_search_results](ferx_search_results.qmd), [ferx_search_space](ferx_search_space.qmd)
Concept
search
Value
An object of class ferx_ruvsearch:
- steps: The step table, one row per fitted model, in the engine’s own column order:
iteration,candidate,feature,screened,parent_ofv,ofv,dofv,df,p_value,alpha,significant,cwres_dofv,selected,converged,passed,failures,seconds- followed byfamily(the feature’s family, which is whatskipnames and what a selection retires) andnote(why a row could not be compared, on its own;failurescarries it too when the gate had nothing to say). A row withscreened = TRUEis a CWRES pre-screen fit: itsofvis on the CWRES scale rather than the data’s, andcwres_dofvis its improvement over the CWRES base - only the feature the screen picked was refitted to the data. - fit: The final model’s fit as a
ferx_fit, orNULLwhen a degraded resume could not recover it. - model_text: Every fitted model’s text, named by candidate id, so a form the search rejected can be read or refitted without re-running it.
final_model_pathis thefinal.ferxwritten beside the run. - final_features, final_families: The features the final model carries beyond the base, in the order they were accepted. Empty when the search returned the input or the proportional base.
- input_model, input_ofv: The model file’s own error model, fitted as given.
- base_model_id, base_ofv: The parent of iteration one:
"input", or"base"when a proportional base had to be derived. - final_model, final_model_id, final_ofv: The winning model’s text, its id, and its objective function value.
- options: The search as the engine read it:
groups,p_value,skip,max_iter,cwres_prescreenandcutoff(thedf = 1chi-square cutoff atp_value). - n_iterations: Iterations actually run.
- candidates: The runner’s candidate table when the run wrote one - see
[ferx_search_results](ferx_search_results.qmd). - notes, cancelled: What the search wants said once (a family not tested and why, a reversion), and whether it was stopped early.
Examples
ex <- ferx_example("one_cpt_iv")
# Inline: no file to author for a one-off
res <- ferx_ruvsearch(
model = ex$model,
data = ex$data,
p_value = 0.05,
max_iter = 2,
directory = "ruvsearch-run-1"
)
res
res$steps[, c("iteration", "feature", "family", "dofv", "p_value", "passed")]
summary(res)
# Reproducible: the .ferxsearch file is the artifact
res2 <- ferx_ruvsearch(config = ex$search, directory = "ruvsearch-run-2")