Skip to content

Commit f252cfb

Browse files
committed
add tidy() methods (closes #58)
1 parent 83bba1a commit f252cfb

12 files changed

+151
-20
lines changed

NAMESPACE

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ S3method(required_pkgs,numeric_range)
2929
S3method(required_pkgs,predictions_custom)
3030
S3method(required_pkgs,probability_calibration)
3131
S3method(required_pkgs,probability_threshold)
32+
S3method(tidy,tailor)
3233
S3method(tunable,equivocal_zone)
3334
S3method(tunable,numeric_calibration)
3435
S3method(tunable,numeric_range)

R/adjust-equivocal-zone.R

-3
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,3 @@ tunable.equivocal_zone <- function(x, ...) {
142142
component_id = "equivocal_zone"
143143
)
144144
}
145-
146-
# todo missing methods:
147-
# todo tidy

R/adjust-numeric-calibration.R

-3
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,3 @@ required_pkgs.numeric_calibration <- function(x, ...) {
130130
tunable.numeric_calibration <- function(x, ...) {
131131
no_param
132132
}
133-
134-
# todo missing methods:
135-
# todo tidy

R/adjust-numeric-range.R

-3
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,3 @@ tunable.numeric_range <- function(x, ...) {
146146
component_id = "numeric_range"
147147
)
148148
}
149-
150-
# todo missing methods:
151-
# todo tidy

R/adjust-predictions-custom.R

-3
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,3 @@ required_pkgs.predictions_custom <- function(x, ...) {
9090
tunable.predictions_custom <- function(x, ...) {
9191
no_param
9292
}
93-
94-
# todo missing methods:
95-
# todo tidy

R/adjust-probability-calibration.R

-3
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,3 @@ required_pkgs.probability_calibration <- function(x, ...) {
138138
tunable.probability_calibration <- function(x, ...) {
139139
no_param
140140
}
141-
142-
# todo missing methods:
143-
# todo tidy

R/adjust-probability-threshold.R

-3
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,3 @@ tunable.probability_threshold <- function(x, ...) {
121121
component_id = "probability_threshold"
122122
)
123123
}
124-
125-
# todo missing methods:
126-
# todo tidy

R/tailor.R

-2
Original file line numberDiff line numberDiff line change
@@ -269,5 +269,3 @@ tunable.tailor <- function(x, ...) {
269269
}
270270
res
271271
}
272-
273-
# todo tidy (this should probably just be `adjustment_orderings()`)

R/tidy.R

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
2+
#' Tidy a tailor object
3+
#'
4+
#' @description
5+
#' Describe a tailor's adjustments in a tibble with one row per adjustment.
6+
#'
7+
#' @param x A [tailor()] object.
8+
#' @param number Optional. A single integer between 1 and the number of
9+
#' adjustments.
10+
#' @param ... Currently unused; must be empty.
11+
#'
12+
#' @returns
13+
#' A tibble containing information about the tailor's adjustments including
14+
#' their ordering, whether they've been trained, and whether they require
15+
#' training with a separate calibration set.
16+
#'
17+
#' @export
18+
tidy.tailor <- function(x, number = NA, ...) {
19+
n_adjustments <- length(x$adjustments)
20+
check_number_whole(
21+
number, min = 1, max = as.double(n_adjustments), allow_na = TRUE
22+
)
23+
check_dots_empty()
24+
if (is.na(number)) {
25+
number <- seq_len(n_adjustments)
26+
}
27+
28+
res <- adjustment_orderings(x$adjustments[number])
29+
30+
res <- vctrs::vec_cbind(
31+
number = number,
32+
res,
33+
trained = purrr::map_lgl(x$adjustments[number], purrr::pluck, "trained"),
34+
requires_training = purrr::map_lgl(
35+
x$adjustments[number], purrr::pluck, "requires_fit"
36+
)
37+
)
38+
39+
tibble::new_tibble(res)
40+
}
41+
42+
tidy_adjustments <- function(adjustments) {
43+
res <- adjustment_orderings(x$adjustments)
44+
45+
res <- vctrs::vec_cbind(
46+
number = seq_len(nrow(res)),
47+
res,
48+
trained = purrr::map_lgl(x$adjustments, purrr::pluck, "trained"),
49+
requires_train = purrr::map_lgl(x$adjustments, purrr::pluck, "requires_fit")
50+
)
51+
52+
tibble::new_tibble(res)
53+
}

man/tidy.tailor.Rd

+24
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/_snaps/tidy.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# tidy.tailor errors informatively with bad arguments
2+
3+
Code
4+
tidy(tlr, number = 4)
5+
Condition
6+
Error in `tidy()`:
7+
! `number` must be a whole number between 1 and 2 or `NA`, not the number 4.
8+

tests/testthat/test-tidy.R

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
test_that("tidy.tailor works", {
2+
library(tibble)
3+
4+
set.seed(1)
5+
d_calibration <- tibble(y = rnorm(100), y_pred = y/2 + rnorm(100))
6+
d_test <- tibble(y = rnorm(100), y_pred = y/2 + rnorm(100))
7+
8+
# TODO: reintroduce custom predictions when #61 is resolved
9+
tlr <-
10+
tailor() %>%
11+
adjust_numeric_calibration() %>%
12+
adjust_numeric_range(lower_limit = 2) #%>%
13+
#adjust_predictions_custom(squared = y_pred^2)
14+
15+
tidy_tlr <- tidy(tlr)
16+
17+
expect_s3_class(tidy_tlr, "tbl_df")
18+
expect_equal(nrow(tidy_tlr), length(tlr$adjustments))
19+
expect_named(
20+
tidy_tlr,
21+
c("number", "name", "input", "output_numeric", "output_prob",
22+
"output_class", "output_all", "trained", "requires_training")
23+
)
24+
expect_equal(tidy_tlr$number, seq_len(length(tlr$adjustments)))
25+
expect_false(any(tidy_tlr$trained))
26+
expect_true(any(tidy_tlr$requires_training))
27+
28+
tidy_tlr_1 <- tidy(tlr, 1)
29+
tidy_tlr_2 <- tidy(tlr, 2)
30+
31+
expect_equal(tidy_tlr[1,], tidy_tlr_1)
32+
expect_equal(tidy_tlr[2,], tidy_tlr_2)
33+
34+
tlr_fit <- fit(tlr, d_calibration, outcome = y, estimate = y_pred)
35+
36+
tidy_tlr_fit <- tidy(tlr_fit)
37+
38+
expect_identical(
39+
tidy_tlr[names(tidy_tlr) != "trained"],
40+
tidy_tlr_fit[names(tidy_tlr_fit) != "trained"]
41+
)
42+
expect_true(all(tidy_tlr_fit$trained))
43+
})
44+
45+
test_that("tidy.tailor errors informatively with bad arguments", {
46+
tlr <-
47+
tailor() %>%
48+
adjust_numeric_calibration() %>%
49+
adjust_numeric_range(lower_limit = 2)
50+
51+
expect_error(tidy(tlr, silly = "head"), class = "rlib_error_dots_nonempty")
52+
expect_snapshot(error = TRUE, tidy(tlr, number = 4))
53+
})
54+
55+
test_that("tidying a tailor with no adjustments", {
56+
tidy_tlr <- tidy(tailor())
57+
58+
expect_equal(nrow(tidy_tlr), 0)
59+
expect_equal(
60+
ncol(tidy_tlr),
61+
tailor() %>%
62+
adjust_numeric_calibration() %>%
63+
tidy() %>%
64+
ncol())
65+
})

0 commit comments

Comments
 (0)