Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nlmixr2::nlmixr2 - Workflow helper for saving/loading runs. #168

Open
iamstein opened this issue Jun 27, 2023 · 4 comments
Open

nlmixr2::nlmixr2 - Workflow helper for saving/loading runs. #168

iamstein opened this issue Jun 27, 2023 · 4 comments

Comments

@iamstein
Copy link

iamstein commented Jun 27, 2023

As a new user, I'm working out what a nlimxr2 workflow should be. I'd like to programmatically capture all the runs I'm performing in Rmarkdown, providing various outputs and diagnostics. And I'd also like to be able to update and rerun this document without re-executing all the fits. In talking with Matt, I think we both use something like the function below that saves the output to a file, and then if that file exists, just load it in rather than overwrite.

This is also more similar to how NONMEM and Monolix work, where the output of any model does get saved each time the model runs.

If you all thought something like this was helpful, it would be great if it were part of the package rather me using my own custom function. So I just wanted to offer the idea, here. There may very well be better ways to accomplish this task as well. I wanted to make "overwrite = TRUE" a default behavior such that input is not required and it works more like Monolix and NONMEM, but if I make that option to be optional, I think it messed up the "..." input to the nlmixr2 function and I wasn't sure how to fix that.

ams_nlmixr2 = function(filename, overwrite, ...) {
# if the file "filename" doesn't exist, run and saves nlimxr2 fit to the filename
# if the file "filename" does exist, load the nlmixr2 fit from that filename
#
# overwrite if TRUE will force an overwrite of the saved file
# overwrite if FALSE will load the saved file if it exists
  if ((!file.exists(filename)) | overwrite == TRUE) {
    run = nlmixr2(...)
    qs::qsave(run, filename)
  } else {
    run = qs::qread(filename)
    message(paste0("Loading ", filename, " - Last modified on: ", file.info(filename)$mtime))
  }
  return(run)
}
@iamstein iamstein changed the title nlmixr2::nlmixr2 - Workflow helper for saving/roading runs. nlmixr2::nlmixr2 - Workflow helper for saving/loading runs. Jun 27, 2023
@mattfidler
Copy link
Contributor

We could use model/data md5 hash.

On the other hand, I believe there is also a makefile like approach with targets though I haven't used it:

https://github.com/nlmixr2/nlmixr2targets

In this case the entire analysis could be triggered (or not) depending on if any of its dependencies were changed. It is a bit more to setup though it is likely more powerful.

It would also be nice if it somehow produced outputs compatible with shinyMixR for those who like run tracking, comparison, etc.

@billdenney
Copy link
Contributor

I heavily use targets for my model workflows (ergo my creation of the nlmixr2targets package).

I'd advocate for a solution like targets rather than wrapping a "save my most recent run" function as it will ensure reproducibility. It has the benefit that all runs get rerun when new data are introduced. I have also written in a data simplification step so that if data not used by a model is changed, the model is not rerun (e.g. if you add a covariate column to the dataset, models not using that covariate column will not rerun).

The disadvantage is that targets requires a particular type of structured workflow which will be more complicated for users.

@mattfidler
Copy link
Contributor

I think you could also use shinyMixR perhaps as a run manager.

@mattfidler
Copy link
Contributor

A problem with loading these items is the simple amount of memory used. Perhaps offload everything to a saved file would be helpful.

All data frames could be accessed with vroom::vroom() and the other items could be loaded on the fly. I have tried to keep the objects to a minimum and this could be a way to have a very small object simply load the files for the run. It could also make it reaadable by other software too, I suppose.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants