Skip to content

Commit 74d36ad

Browse files
authored
Add error messaging when a step argument that cannot be varying is set to varying() (#135)
1 parent 8650afd commit 74d36ad

File tree

3 files changed

+68
-6
lines changed

3 files changed

+68
-6
lines changed

NEWS.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
## Bug fixes
44

5+
* For the recipes step method of `varying_args()`, there is now error checking
6+
to catch if a user tries to specify an argument that _cannot_ be varying as
7+
varying (for example, the `id`) (#132).
8+
9+
* `find_varying()`, the internal function for detecting varying arguments,
10+
now returns correct results when a size 0 argument is provided. It can also now
11+
detect varying arguments nested deeply into a call (#131, #134).
12+
513
* For multinomial regression, the `.pred_` prefix is now only added to prediction
614
column names once (#107).
715

R/varying.R

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,20 +101,32 @@ varying_args.recipe <- function(x, id = NULL, ...) {
101101
#' @rdname varying_args
102102
varying_args.step <- function(x, id = NULL, ...) {
103103
cl <- match.call()
104-
if (!is.null(id) && !is.character(id))
104+
105+
if (!is.null(id) && !is.character(id)) {
105106
stop ("`id` should be a single character string.", call. = FALSE)
107+
}
108+
106109
id <- id[1]
107110

108-
if (is.null(id))
111+
if (is.null(id)) {
109112
id <- deparse(cl$x)
113+
}
114+
115+
# Grab the step class before the subset, as that removes the class
116+
step_type <- class(x)[1]
110117

111-
exclude <-
112-
c("terms", "role", "trained", "skip", "na.rm", "impute_with", "seed",
113-
"prefix", "naming", "denom", "outcome", "id")
114-
x <- x[!(names(x) %in% exclude)]
118+
# Remove NULL argument steps. These are reserved
119+
# for deprecated args or those set at prep() time.
115120
x <- x[!map_lgl(x, is.null)]
121+
116122
res <- map_lgl(x, find_varying)
117123

124+
# ensure the user didn't specify a non-varying argument as varying()
125+
validate_only_allowed_step_args(res, step_type)
126+
127+
# remove the non-varying arguments as they are not important
128+
res <- res[!(names(x) %in% non_varying_step_arguments)]
129+
118130
tibble(
119131
name = names(res),
120132
varying = unname(res),
@@ -123,6 +135,37 @@ varying_args.step <- function(x, id = NULL, ...) {
123135
)
124136
}
125137

138+
validate_only_allowed_step_args <- function(x, step_type) {
139+
140+
check_allowed_arg <- function(x, nm) {
141+
142+
# not varying
143+
if (rlang::is_false(x)) {
144+
return(invisible(x))
145+
}
146+
147+
# not a non-varying step arg name
148+
bad_nm <- nm %in% non_varying_step_arguments
149+
if (!bad_nm) {
150+
return(invisible(x))
151+
}
152+
153+
rlang::abort(glue::glue(
154+
"The following argument for a recipe step of type ",
155+
"'{step_type}' is not allowed to vary: '{nm}'."
156+
))
157+
}
158+
159+
purrr::iwalk(x, check_allowed_arg)
160+
invisible(x)
161+
}
162+
163+
non_varying_step_arguments <- c(
164+
"terms", "role", "trained", "skip",
165+
"na.rm", "impute_with", "seed",
166+
"prefix", "naming", "denom", "outcome", "id"
167+
)
168+
126169
# helpers ----------------------------------------------------------------------
127170

128171
is_varying <- function(x) {

tests/testthat/test_varying.R

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,14 @@ test_that("varying() deeply nested in calls can be located - #134", {
147147
TRUE
148148
)
149149
})
150+
151+
test_that("recipe steps with non-varying args error if specified as varying()", {
152+
153+
rec_bad_varying <- rec_1
154+
rec_bad_varying$steps[[1]]$skip <- varying()
155+
156+
expect_error(
157+
varying_args(rec_bad_varying),
158+
"The following argument for a recipe step of type 'step_center' is not allowed to vary: 'skip'."
159+
)
160+
})

0 commit comments

Comments
 (0)