diff --git a/R/defaults.R b/R/defaults.R deleted file mode 100644 index ab096aac3..000000000 --- a/R/defaults.R +++ /dev/null @@ -1,57 +0,0 @@ -#' Default method for data validation -#' -#' @inheritParams epidist_validate -#' @param ... Additional arguments passed to method. -#' @family defaults -#' @export -epidist_validate.default <- function(data, ...) { - cli_abort( - "No epidist_validate method implemented for the class ", class(data), "\n", - "See methods(epidist_validate) for available methods" - ) -} - -#' Default method for defining model specific Stan code -#' -#' @inheritParams epidist_stancode -#' @param ... Additional arguments passed to method. -#' @family defaults -#' @export -epidist_stancode.default <- function(data, ...) { - cli_abort( - "No epidist_stancode method implemented for the class ", class(data), "\n", - "See methods(epidist_stancode) for available methods" - ) -} - -#' Default method used for interface using `brms` -#' -#' @inheritParams epidist -#' @inheritParams epidist_formula -#' @rdname epidist.default -#' @method epidist default -#' @family defaults -#' @export -epidist.default <- function(data, formula = brms::bf(mu ~ 1), - family = "lognormal", prior = NULL, - backend = "cmdstanr", fn = brms::brm, ...) { - epidist_validate(data) - epidist_family <- epidist_family(data, family) - epidist_formula <- epidist_formula( - data = data, family = epidist_family, formula = formula - ) - epidist_prior <- epidist_prior( - data = data, family = family, formula = epidist_formula, prior - ) - epidist_stancode <- epidist_stancode( - data = data, family = epidist_family, formula = epidist_formula - ) - fit <- fn( - formula = epidist_formula, family = epidist_family, prior = epidist_prior, - stanvars = epidist_stancode, backend = backend, data = data, ... - ) - - class(fit) <- c(class(fit), "epidist_fit") - - return(fit) -} diff --git a/R/generics.R b/R/fit.R similarity index 51% rename from R/generics.R rename to R/fit.R index cd5d70147..b712cf350 100644 --- a/R/generics.R +++ b/R/fit.R @@ -1,36 +1,7 @@ -#' Validate a data object for use with [epidist()] -#' -#' This function validates that the provided `data` is suitable to run a -#' particular `epidist` model. This may include checking the class of `data`, -#' and that it contains suitable columns. -#' -#' @param data A `data.frame` containing line list data. -#' @family generics -#' @export -epidist_validate <- function(data) { - UseMethod("epidist_validate") -} - -#' Define model specific Stan code -#' -#' This function is used within [epidist()] to create any custom Stan code which -#' is injected into `brms` via the `stanvars` argument. It is unlikely that -#' as a user you will need this function, but we export it nonetheless to be -#' transparent about what exactly is happening inside of a call to [epidist()]. -#' -#' @inheritParams epidist_validate -#' @param ... Additional arguments passed to method. -#' @rdname epidist_stancode -#' @family generics -#' @export -epidist_stancode <- function(data, ...) { - UseMethod("epidist_stancode") -} - #' Fit epidemiological delay distributions using a `brms` interface #' #' @inheritParams epidist_validate -#' @param formula A formula object created using [brms::bf()]. A formula must be +#' @param formula A formula object created using `brms::bf`. A formula must be #' provided for the distributional parameter `mu` common to all `brms` families. #' Optionally, formulas may also be provided for additional distributional #' parameters. @@ -46,14 +17,43 @@ epidist_stancode <- function(data, ...) { #' @param backend Character string naming the package to use as the backend for #' fitting the Stan model. Options are `"rstan"` and `"cmdstanr"` (the default). #' This option is passed directly through to `fn`. -#' @param fn The internal function to be called. By default this is -#' [brms::brm()] which performs inference for the specified model. Other options -#' [brms::make_stancode()], which returns the Stan code for the specified model, -#' and [brms::make_standata()] which returns the data passed to Stan. These +#' @param fn The internal function to be called. By default this is `brms::brm`, +#' which performs inference for the specified model. Other options +#' `brms::make_stancode`, which returns the Stan code for the specified model, +#' and `brms::make_standata` which returns the data passed to Stan. These #' options may be useful for model debugging and extensions. #' @param ... Additional arguments for method. -#' @family generics +#' @family fit #' @export epidist <- function(data, formula, family, prior, backend, fn, ...) { UseMethod("epidist") } + +#' Default method used for interface using `brms` +#' +#' @inheritParams epidist +#' @rdname epidist.default +#' @method epidist default +#' @family fit +#' @export +epidist.default <- function(data, formula = brms::bf(mu ~ 1), + family = "lognormal", prior = NULL, + backend = "cmdstanr", fn = brms::brm, ...) { + epidist_validate(data) + epidist_family <- epidist_family(data, family) + epidist_formula <- epidist_formula( + data = data, family = epidist_family, formula = formula + ) + epidist_prior <- epidist_prior( + data = data, family = family, formula = epidist_formula, prior + ) + epidist_stancode <- epidist_stancode( + data = data, family = epidist_family, formula = epidist_formula + ) + fit <- fn( + formula = epidist_formula, family = epidist_family, prior = epidist_prior, + stanvars = epidist_stancode, backend = backend, data = data, ... + ) + class(fit) <- c(class(fit), "epidist_fit") + return(fit) +} diff --git a/R/latent_individual.R b/R/latent_individual.R index 55c8d7211..86146e106 100644 --- a/R/latent_individual.R +++ b/R/latent_individual.R @@ -72,10 +72,11 @@ as_latent_individual.data.frame <- function(data) { #' `data.frame` with the correct columns. #' #' @param data A `data.frame` containing line list data +#' @param ... ... #' @method epidist_validate epidist_latent_individual #' @family latent_individual #' @export -epidist_validate.epidist_latent_individual <- function(data) { +epidist_validate.epidist_latent_individual <- function(data, ...) { assert_true(is_latent_individual(data)) assert_latent_individual_input(data) assert_names( diff --git a/R/stancode.R b/R/stancode.R new file mode 100644 index 000000000..669e7cf22 --- /dev/null +++ b/R/stancode.R @@ -0,0 +1,25 @@ +#' Define model specific Stan code +#' +#' This function is used within [epidist()] to create any custom Stan code which +#' is injected into `brms` via the `stanvars` argument. It is unlikely that +#' as a user you will need this function, but we export it nonetheless to be +#' transparent about what exactly is happening inside of a call to [epidist()]. +#' +#' @inheritParams epidist_validate +#' @param ... Additional arguments passed to method. +#' @rdname epidist_stancode +#' @family stan +#' @export +epidist_stancode <- function(data, ...) { + UseMethod("epidist_stancode") +} + +#' Default method for defining model specific Stan code +#' +#' @inheritParams epidist_stancode +#' @param ... Additional arguments passed to method. +#' @family stan +#' @export +epidist_stancode.default <- function(data, ...) { + return(NULL) +} diff --git a/R/validate.R b/R/validate.R new file mode 100644 index 000000000..65d86d884 --- /dev/null +++ b/R/validate.R @@ -0,0 +1,26 @@ +#' Validate a data object for use with [epidist()] +#' +#' This function validates that the provided `data` is suitable to run a +#' particular `epidist` model. This may include checking the class of `data`, +#' and that it contains suitable columns. +#' +#' @param data A `data.frame` containing line list data. +#' @param ... Additional arguments passed to method. +#' @family validate +#' @export +epidist_validate <- function(data, ...) { + UseMethod("epidist_validate") +} + +#' Default method for data validation +#' +#' @inheritParams epidist_validate +#' @param ... Additional arguments passed to method. +#' @family validate +#' @export +epidist_validate.default <- function(data, ...) { + cli_abort( + "No epidist_validate method implemented for the class ", class(data), "\n", + "See methods(epidist_validate) for available methods" + ) +} diff --git a/_pkgdown.yml b/_pkgdown.yml index cf80bfada..f5ef239b1 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -41,14 +41,10 @@ reference: desc: Functions for preprocessing data contents: - has_concept("preprocess") -- title: S3 generics - desc: S3 generics for delay modelling +- title: Validation + desc: Functions used to check validity of package objects contents: - - has_concept("generics") -- title: Method default - desc: Default methods for S3 generics - contents: - - has_concept("defaults") + - has_concept("validate") - title: Family desc: Functions related to specifying custom `brms` families contents: @@ -57,10 +53,18 @@ reference: desc: Functions related to specifying custom `brms` formula contents: - has_concept("formula") -- title: Priors +- title: Prior distributions desc: Functions for specifying prior distributions contents: - has_concept("prior") +- title: Stan code + desc: Functions for specifying custom Stan code to put into `brms` + contents: + - has_concept("stan") +- title: Model fitting + desc: Functions for fitting delay distribution models using `brms` + contents: + - has_concept("fit") - title: Latent individual model desc: Specific methods for the latent individual model contents: diff --git a/man/epidist.Rd b/man/epidist.Rd index 6ace0b497..dbb162aa5 100644 --- a/man/epidist.Rd +++ b/man/epidist.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/generics.R +% Please edit documentation in R/fit.R \name{epidist} \alias{epidist} \title{Fit epidemiological delay distributions using a \code{brms} interface} @@ -41,8 +41,7 @@ options may be useful for model debugging and extensions.} Fit epidemiological delay distributions using a \code{brms} interface } \seealso{ -Other generics: -\code{\link{epidist_stancode}()}, -\code{\link{epidist_validate}()} +Other fit: +\code{\link{epidist.default}()} } -\concept{generics} +\concept{fit} diff --git a/man/epidist.default.Rd b/man/epidist.default.Rd index 6dac69030..376fb7645 100644 --- a/man/epidist.default.Rd +++ b/man/epidist.default.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/defaults.R +% Please edit documentation in R/fit.R \name{epidist.default} \alias{epidist.default} \title{Default method used for interface using \code{brms}} @@ -49,8 +49,7 @@ options may be useful for model debugging and extensions.} Default method used for interface using \code{brms} } \seealso{ -Other defaults: -\code{\link{epidist_stancode.default}()}, -\code{\link{epidist_validate.default}()} +Other fit: +\code{\link{epidist}()} } -\concept{defaults} +\concept{fit} diff --git a/man/epidist_stancode.Rd b/man/epidist_stancode.Rd index 3ed292a52..d86c8010d 100644 --- a/man/epidist_stancode.Rd +++ b/man/epidist_stancode.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/generics.R +% Please edit documentation in R/stancode.R \name{epidist_stancode} \alias{epidist_stancode} \title{Define model specific Stan code} @@ -18,8 +18,7 @@ as a user you will need this function, but we export it nonetheless to be transparent about what exactly is happening inside of a call to \code{\link[=epidist]{epidist()}}. } \seealso{ -Other generics: -\code{\link{epidist}()}, -\code{\link{epidist_validate}()} +Other stan: +\code{\link{epidist_stancode.default}()} } -\concept{generics} +\concept{stan} diff --git a/man/epidist_stancode.default.Rd b/man/epidist_stancode.default.Rd index 7154370dd..1aa781741 100644 --- a/man/epidist_stancode.default.Rd +++ b/man/epidist_stancode.default.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/defaults.R +% Please edit documentation in R/stancode.R \name{epidist_stancode.default} \alias{epidist_stancode.default} \title{Default method for defining model specific Stan code} @@ -15,8 +15,7 @@ Default method for defining model specific Stan code } \seealso{ -Other defaults: -\code{\link{epidist.default}()}, -\code{\link{epidist_validate.default}()} +Other stan: +\code{\link{epidist_stancode}()} } -\concept{defaults} +\concept{stan} diff --git a/man/epidist_validate.Rd b/man/epidist_validate.Rd index f30fc94cb..bccd9b855 100644 --- a/man/epidist_validate.Rd +++ b/man/epidist_validate.Rd @@ -1,13 +1,15 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/generics.R +% Please edit documentation in R/validate.R \name{epidist_validate} \alias{epidist_validate} \title{Validate a data object for use with \code{\link[=epidist]{epidist()}}} \usage{ -epidist_validate(data) +epidist_validate(data, ...) } \arguments{ \item{data}{A \code{data.frame} containing line list data.} + +\item{...}{Additional arguments passed to method.} } \description{ This function validates that the provided \code{data} is suitable to run a @@ -15,8 +17,7 @@ particular \code{epidist} model. This may include checking the class of \code{da and that it contains suitable columns. } \seealso{ -Other generics: -\code{\link{epidist}()}, -\code{\link{epidist_stancode}()} +Other validate: +\code{\link{epidist_validate.default}()} } -\concept{generics} +\concept{validate} diff --git a/man/epidist_validate.default.Rd b/man/epidist_validate.default.Rd index 9c0787ffa..e1c12f87a 100644 --- a/man/epidist_validate.default.Rd +++ b/man/epidist_validate.default.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/defaults.R +% Please edit documentation in R/validate.R \name{epidist_validate.default} \alias{epidist_validate.default} \title{Default method for data validation} @@ -15,8 +15,7 @@ Default method for data validation } \seealso{ -Other defaults: -\code{\link{epidist.default}()}, -\code{\link{epidist_stancode.default}()} +Other validate: +\code{\link{epidist_validate}()} } -\concept{defaults} +\concept{validate} diff --git a/man/epidist_validate.epidist_latent_individual.Rd b/man/epidist_validate.epidist_latent_individual.Rd index 81d82e537..986b13ded 100644 --- a/man/epidist_validate.epidist_latent_individual.Rd +++ b/man/epidist_validate.epidist_latent_individual.Rd @@ -4,10 +4,12 @@ \alias{epidist_validate.epidist_latent_individual} \title{Validate latent individual model data} \usage{ -\method{epidist_validate}{epidist_latent_individual}(data) +\method{epidist_validate}{epidist_latent_individual}(data, ...) } \arguments{ \item{data}{A \code{data.frame} containing line list data} + +\item{...}{...} } \description{ This function checks whether the provided \code{data} object is suitable for diff --git a/tests/testthat/test-latent_individual.R b/tests/testthat/test-latent_individual.R index 9aafac4c5..5675c4c96 100644 --- a/tests/testthat/test-latent_individual.R +++ b/tests/testthat/test-latent_individual.R @@ -50,5 +50,12 @@ test_that("epidist_validate.epidist_latent_individual returns FALSE for incorrec }) test_that("epidist_stancode.epidist_latent_individual produces valid stanvars", { # nolint: line_length_linter. - expect_equal(1, 1) + epidist_family <- epidist_family(prep_obs) + epidist_formula <- epidist_formula( + prep_obs, epidist_family, formula = brms::bf(mu ~ 1) + ) + stancode <- epidist_stancode( + prep_obs, family = epidist_family, formula = epidist_formula + ) + expect_s3_class(stancode, "stanvars") }) diff --git a/tests/testthat/test-stancode.R b/tests/testthat/test-stancode.R new file mode 100644 index 000000000..898740509 --- /dev/null +++ b/tests/testthat/test-stancode.R @@ -0,0 +1,3 @@ +test_that("epidist_stancode.default returns NULL", { # nolint: line_length_linter. + expect_null(epidist_stancode(data.frame())) +})