Skip to content

Commit

Permalink
Load custom models (#20)
Browse files Browse the repository at this point in the history
* Create .devcontainer and update Dockerfile

* Update gitignore and Makefile with dev command

* Enable passing filepath to custom models

* Prepend (custom) label to custom models

* Add reading model description .md file to app.R

* Delete .DS_Store

* Update actions/upload-artifact version to v3

* Update getting_started vignette to include newest changes

* Update actions/upload-artifact version to v4

* Update docs

* Add devcontainer to Rbuildignore

* Add default value to models_setup input

* Update DESCRIPTION version num and date, add Andrew as author

* Add details on custom_models_path to both app.R and functions-ui.R

* Update failed examples

* Remove failing examples
  • Loading branch information
apulsipher authored Feb 24, 2025
1 parent d96f33f commit a58e029
Show file tree
Hide file tree
Showing 12 changed files with 109 additions and 11 deletions.
Binary file removed .DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ README.html
Dockerimage
epishiny
Dockerfile
.devcontainer

# Adding the vignettes as these are heavy
vignettes/
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile → .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM rocker/tidyverse:4.3.3
FROM rocker/tidyverse:4.4.1

# Installing only packages that are not already installed in the base image
RUN install2.r -s \
Expand Down
24 changes: 24 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
// Dev container name
"name": "epiworldRShiny",
// Build image from Dockerfile
"build": {
// Path is relative to the devcontainer.json file.
"dockerfile": "Dockerfile"
}

// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "uname -a",

// Configure tool-specific properties.
// "customizations": {},

// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.Rproj.user
.Rhistory
.secrets.R
.secrets.R

*.DS_Store
8 changes: 5 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
Package: epiworldRShiny
Type: Package
Title: A 'shiny' Wrapper of the R Package 'epiworldR'
Version: 0.1-1
Date: 2025-01-30
Version: 0.1-2
Date: 2025-02-18
Authors@R: c(
person("George", "Vega Yon", role=c("aut"),
email="[email protected]", comment = c(ORCID = "0000-0002-3171-0844")),
person("Derek", "Meyer", role=c("aut","cre"),
email="[email protected]", comment = c(ORCID = "0009-0005-1350-6988")),
person("Andrew", "Pulsipher", role=c("aut"),
email="[email protected]", comment = c(ORCID = "0000-0002-0773-3210")),
person("Centers for Disease Control and Prevention", role="fnd", comment = "Award number 1U01CK000585; 75D30121F00003"
),
person("Lindsay", "Keegan", role=c("ctb"), email="[email protected]", comment = c(ORCID = "0000-0002-8526-3007")),
Expand All @@ -22,7 +24,7 @@ URL: https://github.com/UofUEpiBio/epiworldRShiny/,
https://uofuepibio.github.io/epiworldRShiny/,
BugReports: https://github.com/UofUEpiBio/epiworldRShiny/issues/
License: MIT + file LICENSE
RoxygenNote: 7.3.1
RoxygenNote: 7.3.2
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
Suggests:
Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ install:
run:
Rscript --vanilla -e 'epiworldRShiny::epiworldRShiny()'

dev: build install run

check:
cd .. && R CMD check $(PKG_NAME)_$(PKG_VERSION).tar.gz

Expand Down
18 changes: 16 additions & 2 deletions R/app.R
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,30 @@ epiworldRenv <- function() {
}

#' @export
#' @param custom_models_path Optional path to custom model files (see details).
#' @details
#' When `custom_models_path` is specified, the function will look for valid model files
#' at the specified path. These will be added to the list of available models.
#' The function expects R files named `shiny_<model_name>.R` which contain the model.
#' The function will also look for optional Markdown files named `shiny_<model_name>.md`
#' which contain the model description.
#' @rdname epiworldRShiny
epiworldRShiny <- function(...) {
epiworldRShiny <- function(custom_models_path = NULL, ...) {

# If the package is not loaded, load it
if (!"epiworldRShiny" %in% search()) {
library(epiworldRShiny)
}

models_setup()
models_setup(custom_models_path)

header <- shinydashboard::dashboardHeader(
title = shiny::HTML(
'epiworldR <text style="color: gray; font-size:50%">(beta)</text>'
)
)

# Sets CSS cursor style for headers
cursor_header_pointer <-
sprintf(
"#npis_header_%1$s, #network_header_%1$s, #population_header_%1$s",
Expand Down Expand Up @@ -148,11 +156,17 @@ epiworldRShiny <- function(...) {
output$model_description <- shiny::renderText({

# Reading the model description from the package
# - First check the prebuilt models
fn <- system.file(
"models", paste0("shiny_", model_id(), ".md"),
package = "epiworldRShiny"
)

# If the model is not found in the prebuilt models, check the custom models
if (!file.exists(fn)) {
fn <- paste0(custom_models_path, paste0("/shiny_", model_id(), ".md"))
}

contents <- if (file.exists(fn))
readLines(fn, warn = FALSE)
else
Expand Down
30 changes: 29 additions & 1 deletion R/functions-ui.R
Original file line number Diff line number Diff line change
Expand Up @@ -299,12 +299,20 @@ seed_input <- function(model_name) {
}

#' @export
#' @param custom_models_path Optional path to custom model files (see details).
#' @details
#' When `custom_models_path` is specified, the function will look for valid model files
#' at the specified path. These will be added to the list of available models.
#' The function expects R files named `shiny_<model_name>.R` which contain the model.
#' @return
#' - `models_setup` returns an object of class list.
#' @rdname epiworldrshiny-ui
#' @examples
#' # Setup with default models only:
#' models_setup()
models_setup <- function() {
#' # Setup with default and custom models:
#' \dontrun{models_setup(custom_models_path = "path/to/custom/models")}
models_setup <- function(custom_models_path = NULL) {

# Getting the environment
env <- parent.frame()
Expand All @@ -318,6 +326,20 @@ models_setup <- function() {
full.names = TRUE
)


# Read in custom models
num_custom_models <- 0
if (!is.null(custom_models_path)) {
custom_models <- list.files(
custom_models_path,
pattern = "shiny_[a-z]+\\.R$",
full.names = TRUE
)

num_custom_models <- length(custom_models)
models <- c(custom_models, models)
}

# Source each model file
for (f in models) {
source(f, local = epiworldRenv())
Expand All @@ -340,6 +362,12 @@ models_setup <- function() {

})

# If model is custom (user-defined), prepend "(custom)"
if (num_custom_models > 0) {
for (i in 1:num_custom_models)
models_names[i] <- paste("(custom)", models_names[i], sep = " ")
}

# Get the model names from the file names
models <- gsub("^.+shiny_([^.]+).R$", "\\1", models)

Expand Down
13 changes: 11 additions & 2 deletions man/epiworldRShiny.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 11 additions & 1 deletion man/epiworldrshiny-ui.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions vignettes/getting_started.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ library(epiworldRShiny)
# epiworldRShiny()
```

The application comes with many pre-built models (SIR, SEIR, etc.), but you can use the app with custom-built models by passing a path to your models when running the app
```
# epiworldRShiny("path/to/custom/models")
```
Custom models will be added to the top of the list of available models (above the pre-built options) and tagged as "(custom)".

## Model set-up

After launching the application, notice the sidebar contains many disease and model parameters which can be modified. Altering these parameters will affect the spread of the infectious disease in the simulated population. Name the disease
Expand Down

0 comments on commit a58e029

Please sign in to comment.