From 9d114ae2b2d02c47c4e3f54910c1d1aa16b4772b Mon Sep 17 00:00:00 2001 From: Gavin Simpson Date: Sat, 14 Dec 2024 18:00:00 +0100 Subject: [PATCH 1/2] fixes #322 --- R/conditional-values.R | 48 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/R/conditional-values.R b/R/conditional-values.R index be192fe0..5c3811dc 100644 --- a/R/conditional-values.R +++ b/R/conditional-values.R @@ -221,6 +221,9 @@ range(x, na.rm = TRUE) } +#' @importFrom scales ordinal_format +#' @importFrom cli format_error qty +#' @importFrom rlang abort `process_condition` <- function(condition, data, variables, n_vals = 100) { # condition: the thing passed as condition to conditional_values # data: a data frame to use for evaluating the fitted values @@ -228,6 +231,51 @@ # n_vals: how many values of the x condition to create c_list <- is.list(condition) nms <- names(condition) + nms_len <- nchar(nms) + # check if any names are "" == 0 characters, for those elements with such + # names, check if that element of conditions is the name of a variable in the + # model. If it is we don't need to do anything. If it isn't, check if it is a + # helper: if it is a helper, throw an error but prompt user to check if they + # forgot to name that element. If it is'nt a helper, throw a less specific + # error + no_nms <- nms_len == 0 + if (any(no_nms)) { + is_zero <- which(no_nms) + # check if the unnamed element contains the name of a variable in the model + nm_in_model <- condition[is_zero] %in% variables + # drop any that are in models + no_nms[is_zero[which(nm_in_model)]] <- FALSE + is_zero <- is_zero[!nm_in_model] + # check if any remaining unnamed elements contain helpers + allowed <- c("threenum", "fivenum", "quartile", "minmax", "decile") + is_allowed <- condition[is_zero] %in% allowed + # report this problem + msg_allowed <- NULL + if (any(is_allowed)) { + which_allowed <- is_zero[is_allowed] + n_allowed <- length(which_allowed) + str_allowed <- scales::ordinal_format()(which_allowed) + msg_allowed <- "The {str_allowed} element{?s} of {.var condition} {?is/are} unnamed, but {?contains a/contains} function name{?s}." + } + # drop any that are helpers + no_nms[is_zero] <- FALSE + is_zero <- is_zero[!is_allowed] + # if there are any remaining, then format a different message + msg_wrong <- NULL + if ((n_wrong <- length(is_zero)) > 0L) { + str_wrong <- scales::ordinal_format()(is_zero) + msg_wrong <- "The {str_wrong} element{?s} of {.var condition} {?is/are} unnamed but {?does/do} not refer to {?a variable/variables} in the model." + } + msg_qty <- length(c(msg_wrong, msg_allowed)) + msg <- c("{.strong Error in the supplied {.var condition}:}", + "x" = msg_wrong, + "x" = msg_allowed, + "i" = "Did you forget to name {qty(msg_qty)} {?this/these} element{?s}?" + ) + if (!is.null(msg_allowed) | !is.null(msg_wrong)) { + rlang::abort(format_error(msg)) + } + } if (is.null(nms)) { nms <- rep(list(NULL), 4) } From dcaaf35d6f8e557f2fee932be54471a5c7147b43 Mon Sep 17 00:00:00 2001 From: Gavin Simpson Date: Sat, 14 Dec 2024 18:00:20 +0100 Subject: [PATCH 2/2] bump version, document() --- DESCRIPTION | 5 +++-- NAMESPACE | 4 ++++ NEWS.md | 4 +++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 66c6e3fb..e34a835c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,5 +1,5 @@ Package: gratia -Version: 0.9.2.9013 +Version: 0.9.2.9014 Title: Graceful 'ggplot'-Based Graphics and Other Functions for GAMs Fitted Using 'mgcv' Authors@R: c(person(given = "Gavin L.", family = "Simpson", email = "ucfagls@gmail.com", @@ -33,7 +33,8 @@ Imports: cli, nlme, ggokabeito, - withr + withr, + scales Suggests: gamm4, lme4, diff --git a/NAMESPACE b/NAMESPACE index 1729abd3..a3e2e1bc 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -418,7 +418,9 @@ export(variance_comp) export(vars_from_label) export(which_smooths) export(worm_plot) +importFrom(cli,format_error) importFrom(cli,pluralize) +importFrom(cli,qty) importFrom(cli,style_dim) importFrom(cli,symbol) importFrom(dplyr,"%>%") @@ -533,6 +535,7 @@ importFrom(rlang,"!!") importFrom(rlang,"%||%") importFrom(rlang,":=") importFrom(rlang,.data) +importFrom(rlang,abort) importFrom(rlang,dots_list) importFrom(rlang,enexpr) importFrom(rlang,enquo) @@ -546,6 +549,7 @@ importFrom(rlang,has_name) importFrom(rlang,inject) importFrom(rlang,parse_expr) importFrom(rlang,set_names) +importFrom(scales,ordinal_format) importFrom(stats,IQR) importFrom(stats,as.formula) importFrom(stats,binomial) diff --git a/NEWS.md b/NEWS.md index 5e294a0a..34fb832e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,7 +4,9 @@ * `conditional_values()` and its `draw()` method compute and plot predictions from a fitted GAM that are conditional on one or more covariates. The - function is a wrapper around `fitted_values()` but allows the user simple ways to specify which covariates to condition on and at what values those covariates should take. It provides similar functionality to + function is a wrapper around `fitted_values()` but allows the user simple ways + to specify which covariates to condition on and at what values those + covariates should take. It provides similar functionality to `marginaleffects::plot_predictions()`, but is simpler. See #300. * `penalty()` and `basis()` can now allow the smooth to be reparameterized such