From ba0d4d09ce0a1cbb6c9f3ad0ac8df7fffd33853f Mon Sep 17 00:00:00 2001 From: Andrea Manica Date: Sun, 13 Oct 2024 14:56:25 +0100 Subject: [PATCH] more informative error for workflow_set that was not fitted --- R/add_member.R | 6 +++++- R/sdm_spec_gam.R | 15 ++++++++++++++- .../restructure/a_tidysdm_workflow_options.Rmd | 2 +- man/sdm_spec_gam.Rd | 16 ++++++++++++++++ vignettes/a0_tidysdm_overview.Rmd | 5 ++++- 5 files changed, 40 insertions(+), 4 deletions(-) diff --git a/R/add_member.R b/R/add_member.R index d4d46bc7..d7ed2d00 100644 --- a/R/add_member.R +++ b/R/add_member.R @@ -23,7 +23,7 @@ add_member <- function(x, member, ...) { #' @rdname add_member #' @export add_member.default <- function(x, member, ...) { - stop("no method available for this object type") + stop("no method available for this object type: ", class(member)) } #' @param id the name to be given to this workflow in the `wflow_id` column. @@ -88,6 +88,10 @@ add_member.tune_results <- function(x, member, metric = NULL, id = NULL, ...) { add_member.workflow_set <- function(x, member, metric = NULL, ...) { for (i_wflow in member$wflow_id) { this_res <- workflowsets::extract_workflow_set_result(member, id = i_wflow) + # if the result is an empty list, throw an error (how did we get to such a situation?) + if (length(this_res)==0) { + stop("no result found for workflow ", i_wflow, "; did you forget to fit the workflow?") + } x <- x %>% add_member(this_res, metric = metric, id = i_wflow) } x diff --git a/R/sdm_spec_gam.R b/R/sdm_spec_gam.R index faa8b7f0..484bff31 100644 --- a/R/sdm_spec_gam.R +++ b/R/sdm_spec_gam.R @@ -2,7 +2,19 @@ #' #' This function returns a [parsnip::model_spec] for a General Additive Model to #' be used as a classifier of presences and absences in Species Distribution Model. -#' +#' +#' Note that, when using GAMs in a `workflow_set()`, it is necessary to +#' update the model with [gam_formula()] (see [`parsnip::model_formula`] for a +#' discussion of formulas with special terms in `tidymodels`): +#' \preformatted{ +#' workflow_set( +#' preproc = list(default = my_recipe), +#' models = list(gam = sdm_spec_gam()), +#' cross = TRUE +#' ) \%>\% update_workflow_model("default_gam", +#' spec = sdm_spec_gam(), +#' formula = gam_formula(my_recipe)) +#' } #' @param ... parameters to be passed to [parsnip::gen_additive_mod()] to #' customise the model. See the help of that function for details. #' @param tune character defining the tuning strategy. As there are no hyperparameters @@ -14,6 +26,7 @@ #' my_gam_spec <- sdm_spec_gam() #' @family "sdm model specifications" #' @export +#' @seealso [parsnip::gen_additive_mod()] [gam_formula()] sdm_spec_gam <- function(..., tune = "none") { tune <- rlang::arg_match(tune) diff --git a/data-raw/restructure/a_tidysdm_workflow_options.Rmd b/data-raw/restructure/a_tidysdm_workflow_options.Rmd index 170d6941..cf27565c 100644 --- a/data-raw/restructure/a_tidysdm_workflow_options.Rmd +++ b/data-raw/restructure/a_tidysdm_workflow_options.Rmd @@ -180,7 +180,7 @@ To build a `workflow_set` of different models, the `hyperparameters` we want to For the most commonly used models, `tidysdm` automatically chooses the most important parameters:\ - Generalised Linear Model, using `sdm_spec_glm()`, -\- General Additive Model, using `sdm_spec_gam()`, +\- General Additive Model, using `sdm_spec_gam()` (note that because of the non-standard formula interface of `mgcv`, it is necessary to update the model with `gam_formula()`), \- random forest specs with tuning, using `sdm_spec_rf()`, diff --git a/man/sdm_spec_gam.Rd b/man/sdm_spec_gam.Rd index 897f199c..4b24d405 100644 --- a/man/sdm_spec_gam.Rd +++ b/man/sdm_spec_gam.Rd @@ -22,10 +22,26 @@ a \link[parsnip:model_spec]{parsnip::model_spec} of the model. This function returns a \link[parsnip:model_spec]{parsnip::model_spec} for a General Additive Model to be used as a classifier of presences and absences in Species Distribution Model. } +\details{ +Note that, when using GAMs in a \code{workflow_set()}, it is necessary to +update the model with \code{\link[=gam_formula]{gam_formula()}} (see \code{\link[parsnip:model_formula]{parsnip::model_formula}} for a +discussion of formulas with special terms in \code{tidymodels}): +\preformatted{ +workflow_set( + preproc = list(default = my_recipe), + models = list(gam = sdm_spec_gam()), + cross = TRUE +) \%>\% update_workflow_model("default_gam", + spec = sdm_spec_gam(), + formula = gam_formula(my_recipe)) +} +} \examples{ my_gam_spec <- sdm_spec_gam() } \seealso{ +\code{\link[parsnip:gen_additive_mod]{parsnip::gen_additive_mod()}} \code{\link[=gam_formula]{gam_formula()}} + Other "sdm model specifications": \code{\link{sdm_spec_boost_tree}()}, \code{\link{sdm_spec_glm}()}, diff --git a/vignettes/a0_tidysdm_overview.Rmd b/vignettes/a0_tidysdm_overview.Rmd index 9bde9775..924bfe0f 100644 --- a/vignettes/a0_tidysdm_overview.Rmd +++ b/vignettes/a0_tidysdm_overview.Rmd @@ -428,7 +428,10 @@ tutorial](https://workflowsets.tidymodels.org/articles/tuning-and-comparing-mode The latter three models have tunable hyperparameters. For the most commonly used models, `tidysdm` automatically chooses the most important parameters, but it is possible to fully customise model specifications -(e.g. see the help for `sdm_spec_rf`). +(e.g. see the help for `sdm_spec_rf`). Note that, if you used GAMs with `sdm_spec_gam()`, +it is necessary to update the model with `gam_formula()` due to the non-standard +formula notation of GAMs (see the help +of `sdm_spec_gam()` for an example of how to do this). ```{r workflow_set} lacerta_models <-