diff --git a/R/fingerprint.R b/R/fingerprint.R new file mode 100644 index 00000000..71a95ab0 --- /dev/null +++ b/R/fingerprint.R @@ -0,0 +1,47 @@ +#' Obtain a identifier for the resamples +#' +#' This function returns a hash (or NA) for an attribute that is created when +#' the `rset` was initially constructed. This can be used to compare with other +#' resampling objects to see if they are the same. +#' @param x An `rset` or `tune_results` object. +#' @param ... Not currently used. +#' @return A character value or `NA_character_` if the object was created prior +#' to rsample version 0.1.0. +#' @rdname get_fingerprint +#' @aliases .get_fingerprint +#' @examples +#' set.seed(1) +#' .get_fingerprint(vfold_cv(mtcars)) +#' +#' set.seed(1) +#' .get_fingerprint(vfold_cv(mtcars)) +#' +#' set.seed(2) +#' .get_fingerprint(vfold_cv(mtcars)) +#' +#' set.seed(1) +#' .get_fingerprint(vfold_cv(mtcars, repeats = 2)) +#' @export +.get_fingerprint <- function(x, ...) { + UseMethod(".get_fingerprint") +} + +#' @export +#' @rdname get_fingerprint +.get_fingerprint.default <- function(x, ...) { + cls <- class(x) + cli_abort("No method for objects of class{?es}: {cls}") +} + +#' @export +#' @rdname get_fingerprint +.get_fingerprint.rset <- function(x, ...) { + check_dots_empty() + att <- attributes(x) + if (any(names(att) == "fingerprint")) { + res <- att$fingerprint + } else { + res <- NA_character_ + } + res +} diff --git a/R/misc.R b/R/misc.R index 284763eb..bb202a39 100644 --- a/R/misc.R +++ b/R/misc.R @@ -118,182 +118,6 @@ split_unnamed <- function(x, f) { unname(out) } -#' Obtain a identifier for the resamples -#' -#' This function returns a hash (or NA) for an attribute that is created when -#' the `rset` was initially constructed. This can be used to compare with other -#' resampling objects to see if they are the same. -#' @param x An `rset` or `tune_results` object. -#' @param ... Not currently used. -#' @return A character value or `NA_character_` if the object was created prior -#' to rsample version 0.1.0. -#' @rdname get_fingerprint -#' @aliases .get_fingerprint -#' @examples -#' set.seed(1) -#' .get_fingerprint(vfold_cv(mtcars)) -#' -#' set.seed(1) -#' .get_fingerprint(vfold_cv(mtcars)) -#' -#' set.seed(2) -#' .get_fingerprint(vfold_cv(mtcars)) -#' -#' set.seed(1) -#' .get_fingerprint(vfold_cv(mtcars, repeats = 2)) -#' @export -.get_fingerprint <- function(x, ...) { - UseMethod(".get_fingerprint") -} - -#' @export -#' @rdname get_fingerprint -.get_fingerprint.default <- function(x, ...) { - cls <- class(x) - cli_abort("No method for objects of class{?es}: {cls}") -} - -#' @export -#' @rdname get_fingerprint -.get_fingerprint.rset <- function(x, ...) { - check_dots_empty() - att <- attributes(x) - if (any(names(att) == "fingerprint")) { - res <- att$fingerprint - } else { - res <- NA_character_ - } - res -} - -#' Reverse the analysis and assessment sets -#' -#' This functions "swaps" the analysis and assessment sets of either a single -#' `rsplit` or all `rsplit`s in the `splits` column of an `rset` object. -#' -#' @param x An `rset` or `rsplit` object. -#' @param ... Not currently used. -#' -#' @return An object of the same class as `x` -#' -#' @examples -#' set.seed(123) -#' starting_splits <- vfold_cv(mtcars, v = 3) -#' reverse_splits(starting_splits) -#' reverse_splits(starting_splits$splits[[1]]) -#' -#' @rdname reverse_splits -#' @export -reverse_splits <- function(x, ...) { - UseMethod("reverse_splits") -} - -#' @rdname reverse_splits -#' @export -reverse_splits.default <- function(x, ...) { - cli_abort( - "{.arg x} must be either an {.cls rsplit} or an {.cls rset} object." - ) -} - -#' @rdname reverse_splits -#' @export -reverse_splits.permutations <- function(x, ...) { - cli_abort( - "Permutations cannot have their splits reversed." - ) -} - -#' @rdname reverse_splits -#' @export -reverse_splits.perm_split <- reverse_splits.permutations - -#' @rdname reverse_splits -#' @export -reverse_splits.rsplit <- function(x, ...) { - - rlang::check_dots_empty() - - out_splits <- list( - analysis = as.integer(x, data = "assessment"), - assessment = as.integer(x, data = "analysis") - ) - out_splits <- make_splits(out_splits, x$data) - class(out_splits) <- class(x) - out_splits - -} - -#' @rdname reverse_splits -#' @export -reverse_splits.rset <- function(x, ...) { - - rlang::check_dots_empty() - - x$splits <- purrr::map(x$splits, reverse_splits) - - x -} - -#' "Reshuffle" an rset to re-generate a new rset with the same parameters -#' -#' This function re-generates an rset object, using the same arguments used -#' to generate the original. -#' -#' @param rset The `rset` object to be reshuffled -#' -#' @return An rset of the same class as `rset`. -#' -#' @examples -#' set.seed(123) -#' (starting_splits <- group_vfold_cv(mtcars, cyl, v = 3)) -#' reshuffle_rset(starting_splits) -#' -#' @export -reshuffle_rset <- function(rset) { - if (!inherits(rset, "rset")) { - cli_abort("{.arg rset} must be an {.cls rset} object.") - } - - if (inherits(rset, "manual_rset")) { - cli_abort("{.arg manual_rset} objects cannot be reshuffled.") - } - - # non-random classes is defined below - if (any(non_random_classes %in% class(rset))) { - cls <- class(rset)[[1]] - cli::cli_warn( - "{.fun reshuffle_rset} will return an identical {.cls rset} when called on {.cls {cls}} objects." - ) - if ("validation_set" %in% class(rset)) { - return(rset) - } - } - - rset_type <- class(rset)[[1]] - split_arguments <- .get_split_args(rset) - if (identical(split_arguments$strata, TRUE)) { - cli_abort(c( - "Cannot reshuffle this rset ({.code attr(rset, 'strata')} is {.val TRUE}, not a column identifier)", - i = "If the original object was created with an older version of rsample, try recreating it with the newest version of the package." - )) - } - - do.call( - rset_type, - c(list(data = rset$splits[[1]]$data), split_arguments) - ) -} - -non_random_classes <- c( - "sliding_index", - "sliding_period", - "sliding_window", - "rolling_origin", - "validation_time_split", - "validation_set" -) - #' Get the split arguments from an rset #' @param x An `rset` or `initial_split` object. #' @param allow_strata_false A logical to specify which value to use if no diff --git a/R/nest.R b/R/nested_cv.R similarity index 100% rename from R/nest.R rename to R/nested_cv.R diff --git a/R/reshuffle_rset.R b/R/reshuffle_rset.R new file mode 100644 index 00000000..f4e07b0a --- /dev/null +++ b/R/reshuffle_rset.R @@ -0,0 +1,58 @@ +#' "Reshuffle" an rset to re-generate a new rset with the same parameters +#' +#' This function re-generates an rset object, using the same arguments used +#' to generate the original. +#' +#' @param rset The `rset` object to be reshuffled +#' +#' @return An rset of the same class as `rset`. +#' +#' @examples +#' set.seed(123) +#' (starting_splits <- group_vfold_cv(mtcars, cyl, v = 3)) +#' reshuffle_rset(starting_splits) +#' +#' @export +reshuffle_rset <- function(rset) { + if (!inherits(rset, "rset")) { + cli_abort("{.arg rset} must be an {.cls rset} object.") + } + + if (inherits(rset, "manual_rset")) { + cli_abort("{.arg manual_rset} objects cannot be reshuffled.") + } + + # non-random classes is defined below + if (any(non_random_classes %in% class(rset))) { + cls <- class(rset)[[1]] + cli::cli_warn( + "{.fun reshuffle_rset} will return an identical {.cls rset} when called on {.cls {cls}} objects." + ) + if ("validation_set" %in% class(rset)) { + return(rset) + } + } + + rset_type <- class(rset)[[1]] + split_arguments <- .get_split_args(rset) + if (identical(split_arguments$strata, TRUE)) { + cli_abort(c( + "Cannot reshuffle this rset ({.code attr(rset, 'strata')} is {.val TRUE}, not a column identifier)", + i = "If the original object was created with an older version of rsample, try recreating it with the newest version of the package." + )) + } + + do.call( + rset_type, + c(list(data = rset$splits[[1]]$data), split_arguments) + ) +} + +non_random_classes <- c( + "sliding_index", + "sliding_period", + "sliding_window", + "rolling_origin", + "validation_time_split", + "validation_set" +) diff --git a/R/reverse_splits.R b/R/reverse_splits.R new file mode 100644 index 00000000..5f3f40e4 --- /dev/null +++ b/R/reverse_splits.R @@ -0,0 +1,68 @@ +#' Reverse the analysis and assessment sets +#' +#' This functions "swaps" the analysis and assessment sets of either a single +#' `rsplit` or all `rsplit`s in the `splits` column of an `rset` object. +#' +#' @param x An `rset` or `rsplit` object. +#' @param ... Not currently used. +#' +#' @return An object of the same class as `x` +#' +#' @examples +#' set.seed(123) +#' starting_splits <- vfold_cv(mtcars, v = 3) +#' reverse_splits(starting_splits) +#' reverse_splits(starting_splits$splits[[1]]) +#' +#' @rdname reverse_splits +#' @export +reverse_splits <- function(x, ...) { + UseMethod("reverse_splits") +} + +#' @rdname reverse_splits +#' @export +reverse_splits.default <- function(x, ...) { + cli_abort( + "{.arg x} must be either an {.cls rsplit} or an {.cls rset} object." + ) +} + +#' @rdname reverse_splits +#' @export +reverse_splits.permutations <- function(x, ...) { + cli_abort( + "Permutations cannot have their splits reversed." + ) +} + +#' @rdname reverse_splits +#' @export +reverse_splits.perm_split <- reverse_splits.permutations + +#' @rdname reverse_splits +#' @export +reverse_splits.rsplit <- function(x, ...) { + + rlang::check_dots_empty() + + out_splits <- list( + analysis = as.integer(x, data = "assessment"), + assessment = as.integer(x, data = "analysis") + ) + out_splits <- make_splits(out_splits, x$data) + class(out_splits) <- class(x) + out_splits + +} + +#' @rdname reverse_splits +#' @export +reverse_splits.rset <- function(x, ...) { + + rlang::check_dots_empty() + + x$splits <- purrr::map(x$splits, reverse_splits) + + x +} diff --git a/man/get_fingerprint.Rd b/man/get_fingerprint.Rd index cc912420..d5ebe9bb 100644 --- a/man/get_fingerprint.Rd +++ b/man/get_fingerprint.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/misc.R +% Please edit documentation in R/fingerprint.R \name{.get_fingerprint} \alias{.get_fingerprint} \alias{.get_fingerprint.default} diff --git a/man/nested_cv.Rd b/man/nested_cv.Rd index 84f67acb..d6baa08c 100644 --- a/man/nested_cv.Rd +++ b/man/nested_cv.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/nest.R +% Please edit documentation in R/nested_cv.R \name{nested_cv} \alias{nested_cv} \title{Nested or Double Resampling} diff --git a/man/reshuffle_rset.Rd b/man/reshuffle_rset.Rd index b3ebc6d6..6cbb9016 100644 --- a/man/reshuffle_rset.Rd +++ b/man/reshuffle_rset.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/misc.R +% Please edit documentation in R/reshuffle_rset.R \name{reshuffle_rset} \alias{reshuffle_rset} \title{"Reshuffle" an rset to re-generate a new rset with the same parameters} diff --git a/man/reverse_splits.Rd b/man/reverse_splits.Rd index 101e5a10..b0a94a35 100644 --- a/man/reverse_splits.Rd +++ b/man/reverse_splits.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/misc.R +% Please edit documentation in R/reverse_splits.R \name{reverse_splits} \alias{reverse_splits} \alias{reverse_splits.default} diff --git a/tests/testthat/_snaps/bootci.md b/tests/testthat/_snaps/bootci.md index 8632d77e..46ae8df5 100644 --- a/tests/testthat/_snaps/bootci.md +++ b/tests/testthat/_snaps/bootci.md @@ -28,17 +28,3 @@ Error in `bca_calc()`: ! All statistics have missing values. -# regression intervals - - Code - skip_if(new_rng_snapshots) - set.seed(123) - int_2 <- reg_intervals(mpg ~ disp + wt, data = mtcars, filter = term == "wt", - model_fn = "glm", keep_reps = TRUE) - int_2 - Output - # A tibble: 1 x 7 - term .lower .estimate .upper .alpha .method .replicates - > - 1 wt -5.62 -3.46 -0.955 0.05 student-t [1,001 x 2] - diff --git a/tests/testthat/_snaps/initial.md b/tests/testthat/_snaps/initial_split.md similarity index 100% rename from tests/testthat/_snaps/initial.md rename to tests/testthat/_snaps/initial_split.md diff --git a/tests/testthat/_snaps/make-splits.md b/tests/testthat/_snaps/make-splits.md deleted file mode 100644 index 370a39af..00000000 --- a/tests/testthat/_snaps/make-splits.md +++ /dev/null @@ -1,8 +0,0 @@ -# improper argument - - Code - make_splits("potato") - Condition - Error in `make_splits()`: - ! No method for objects of class: character - diff --git a/tests/testthat/_snaps/strata.md b/tests/testthat/_snaps/make_strata.md similarity index 100% rename from tests/testthat/_snaps/strata.md rename to tests/testthat/_snaps/make_strata.md diff --git a/tests/testthat/_snaps/misc.md b/tests/testthat/_snaps/misc.md index 7f101e47..040b2669 100644 --- a/tests/testthat/_snaps/misc.md +++ b/tests/testthat/_snaps/misc.md @@ -1,158 +1,10 @@ -# reverse_splits is working +# improper argument Code - reverse_splits(1) + make_splits("potato") Condition - Error in `reverse_splits()`: - ! `x` must be either an or an object. - ---- - - Code - reverse_splits(permutes) - Condition - Error in `reverse_splits()`: - ! Permutations cannot have their splits reversed. - ---- - - Code - reverse_splits(permutes$splits[[1]]) - Condition - Error in `reverse_splits()`: - ! Permutations cannot have their splits reversed. - -# reshuffle_rset is working - - Code - reshuffle_rset(rset_subclasses[[non_random_classes[[i]]]]) - Condition - Warning: - `reshuffle_rset()` will return an identical when called on objects. - Output - # Sliding index resampling - # A tibble: 49 x 2 - splits id - - 1 Slice01 - 2 Slice02 - 3 Slice03 - 4 Slice04 - 5 Slice05 - 6 Slice06 - 7 Slice07 - 8 Slice08 - 9 Slice09 - 10 Slice10 - # i 39 more rows - ---- - - Code - reshuffle_rset(rset_subclasses[[non_random_classes[[i]]]]) - Condition - Warning: - `reshuffle_rset()` will return an identical when called on objects. - Output - # Sliding period resampling - # A tibble: 7 x 2 - splits id - - 1 Slice1 - 2 Slice2 - 3 Slice3 - 4 Slice4 - 5 Slice5 - 6 Slice6 - 7 Slice7 - ---- - - Code - reshuffle_rset(rset_subclasses[[non_random_classes[[i]]]]) - Condition - Warning: - `reshuffle_rset()` will return an identical when called on objects. - Output - # Sliding window resampling - # A tibble: 49 x 2 - splits id - - 1 Slice01 - 2 Slice02 - 3 Slice03 - 4 Slice04 - 5 Slice05 - 6 Slice06 - 7 Slice07 - 8 Slice08 - 9 Slice09 - 10 Slice10 - # i 39 more rows - ---- - - Code - reshuffle_rset(rset_subclasses[[non_random_classes[[i]]]]) - Condition - Warning: - `reshuffle_rset()` will return an identical when called on objects. - Output - # Rolling origin forecast resampling - # A tibble: 45 x 2 - splits id - - 1 Slice01 - 2 Slice02 - 3 Slice03 - 4 Slice04 - 5 Slice05 - 6 Slice06 - 7 Slice07 - 8 Slice08 - 9 Slice09 - 10 Slice10 - # i 35 more rows - ---- - - Code - reshuffle_rset(rset_subclasses[[non_random_classes[[i]]]]) - Condition - Warning: - `reshuffle_rset()` will return an identical when called on objects. - Output - # Validation Set Split (0.75/0.25) - # A tibble: 1 x 2 - splits id - - 1 validation - ---- - - Code - reshuffle_rset(rset_subclasses[[non_random_classes[[i]]]]) - Condition - Warning: - `reshuffle_rset()` will return an identical when called on objects. - Output - # A tibble: 1 x 2 - splits id - - 1 validation - ---- - - Cannot reshuffle this rset (`attr(rset, 'strata')` is "TRUE", not a column identifier) - i If the original object was created with an older version of rsample, try recreating it with the newest version of the package. - ---- - - `manual_rset` objects cannot be reshuffled. - ---- - - `rset` must be an object. + Error in `make_splits()`: + ! No method for objects of class: character # get_rsplit() diff --git a/tests/testthat/_snaps/nesting.md b/tests/testthat/_snaps/nested_cv.md similarity index 100% rename from tests/testthat/_snaps/nesting.md rename to tests/testthat/_snaps/nested_cv.md diff --git a/tests/testthat/_snaps/reg_intervals.md b/tests/testthat/_snaps/reg_intervals.md new file mode 100644 index 00000000..95850f88 --- /dev/null +++ b/tests/testthat/_snaps/reg_intervals.md @@ -0,0 +1,14 @@ +# regression intervals + + Code + skip_if(new_rng_snapshots) + set.seed(123) + int_2 <- reg_intervals(mpg ~ disp + wt, data = mtcars, filter = term == "wt", + model_fn = "glm", keep_reps = TRUE) + int_2 + Output + # A tibble: 1 x 7 + term .lower .estimate .upper .alpha .method .replicates + > + 1 wt -5.62 -3.46 -0.955 0.05 student-t [1,001 x 2] + diff --git a/tests/testthat/_snaps/reshuffle_rset.md b/tests/testthat/_snaps/reshuffle_rset.md new file mode 100644 index 00000000..5d416219 --- /dev/null +++ b/tests/testthat/_snaps/reshuffle_rset.md @@ -0,0 +1,132 @@ +# reshuffle_rset is working + + Code + reshuffle_rset(rset_subclasses[[non_random_classes[[i]]]]) + Condition + Warning: + `reshuffle_rset()` will return an identical when called on objects. + Output + # Sliding index resampling + # A tibble: 49 x 2 + splits id + + 1 Slice01 + 2 Slice02 + 3 Slice03 + 4 Slice04 + 5 Slice05 + 6 Slice06 + 7 Slice07 + 8 Slice08 + 9 Slice09 + 10 Slice10 + # i 39 more rows + +--- + + Code + reshuffle_rset(rset_subclasses[[non_random_classes[[i]]]]) + Condition + Warning: + `reshuffle_rset()` will return an identical when called on objects. + Output + # Sliding period resampling + # A tibble: 7 x 2 + splits id + + 1 Slice1 + 2 Slice2 + 3 Slice3 + 4 Slice4 + 5 Slice5 + 6 Slice6 + 7 Slice7 + +--- + + Code + reshuffle_rset(rset_subclasses[[non_random_classes[[i]]]]) + Condition + Warning: + `reshuffle_rset()` will return an identical when called on objects. + Output + # Sliding window resampling + # A tibble: 49 x 2 + splits id + + 1 Slice01 + 2 Slice02 + 3 Slice03 + 4 Slice04 + 5 Slice05 + 6 Slice06 + 7 Slice07 + 8 Slice08 + 9 Slice09 + 10 Slice10 + # i 39 more rows + +--- + + Code + reshuffle_rset(rset_subclasses[[non_random_classes[[i]]]]) + Condition + Warning: + `reshuffle_rset()` will return an identical when called on objects. + Output + # Rolling origin forecast resampling + # A tibble: 45 x 2 + splits id + + 1 Slice01 + 2 Slice02 + 3 Slice03 + 4 Slice04 + 5 Slice05 + 6 Slice06 + 7 Slice07 + 8 Slice08 + 9 Slice09 + 10 Slice10 + # i 35 more rows + +--- + + Code + reshuffle_rset(rset_subclasses[[non_random_classes[[i]]]]) + Condition + Warning: + `reshuffle_rset()` will return an identical when called on objects. + Output + # Validation Set Split (0.75/0.25) + # A tibble: 1 x 2 + splits id + + 1 validation + +--- + + Code + reshuffle_rset(rset_subclasses[[non_random_classes[[i]]]]) + Condition + Warning: + `reshuffle_rset()` will return an identical when called on objects. + Output + # A tibble: 1 x 2 + splits id + + 1 validation + +--- + + Cannot reshuffle this rset (`attr(rset, 'strata')` is "TRUE", not a column identifier) + i If the original object was created with an older version of rsample, try recreating it with the newest version of the package. + +--- + + `manual_rset` objects cannot be reshuffled. + +--- + + `rset` must be an object. + diff --git a/tests/testthat/_snaps/reverse_splits.md b/tests/testthat/_snaps/reverse_splits.md new file mode 100644 index 00000000..4c15f64c --- /dev/null +++ b/tests/testthat/_snaps/reverse_splits.md @@ -0,0 +1,24 @@ +# reverse_splits is working + + Code + reverse_splits(1) + Condition + Error in `reverse_splits()`: + ! `x` must be either an or an object. + +--- + + Code + reverse_splits(permutes) + Condition + Error in `reverse_splits()`: + ! Permutations cannot have their splits reversed. + +--- + + Code + reverse_splits(permutes$splits[[1]]) + Condition + Error in `reverse_splits()`: + ! Permutations cannot have their splits reversed. + diff --git a/tests/testthat/_snaps/validation.md b/tests/testthat/_snaps/validation_split.md similarity index 100% rename from tests/testthat/_snaps/validation.md rename to tests/testthat/_snaps/validation_split.md diff --git a/tests/testthat/test-bootci.R b/tests/testthat/test-bootci.R index 893a24aa..119a4c8e 100644 --- a/tests/testthat/test-bootci.R +++ b/tests/testthat/test-bootci.R @@ -234,58 +234,6 @@ test_that("bad input", { # ------------------------------------------------------------------------------ -test_that("regression intervals", { - skip_if_not_installed("broom") - skip_on_cran() - - expect_error( - { - set.seed(1) - int_1 <- reg_intervals(mpg ~ disp + wt, data = mtcars) - }, - regexp = NA - ) - - expect_equal( - names(int_1), - c("term", ".lower", ".estimate", ".upper", ".alpha", ".method") - ) - - expect_snapshot({ - skip_if(new_rng_snapshots) - set.seed(123) - int_2 <- reg_intervals( - mpg ~ disp + wt, - data = mtcars, - filter = term == "wt", - model_fn = "glm", - keep_reps = TRUE - ) - int_2 - }) - - expect_equal( - names(int_2), - c("term", ".lower", ".estimate", ".upper", ".alpha", ".method", ".replicates") - ) - expect_true(nrow(int_2) == 1) - expect_true(all(int_2$term == "wt")) - - - expect_error( - reg_intervals(mpg ~ disp + wt, data = mtcars, model_fn = "potato"), - "`model_fn` must be one of" - ) - expect_error( - reg_intervals(mpg ~ disp + wt, data = mtcars, type = "random"), - "`type` must be one of" - ) - expect_error( - reg_intervals(mpg ~ disp + wt, data = mtcars, alpha = "a"), - "must be a single numeric value" - ) -}) - test_that("compute intervals with additional grouping terms", { skip_if_not_installed("broom") diff --git a/tests/testthat/test-for-pred.R b/tests/testthat/test-form_pred.R similarity index 100% rename from tests/testthat/test-for-pred.R rename to tests/testthat/test-form_pred.R diff --git a/tests/testthat/test-initial.R b/tests/testthat/test-initial_split.R similarity index 100% rename from tests/testthat/test-initial.R rename to tests/testthat/test-initial_split.R diff --git a/tests/testthat/test-make-splits.R b/tests/testthat/test-make-splits.R deleted file mode 100644 index 2342a735..00000000 --- a/tests/testthat/test-make-splits.R +++ /dev/null @@ -1,60 +0,0 @@ -test_that("can create a split with an empty assessment set (#188)", { - df <- data.frame(x = c(1, 2, 3, 4)) - indices <- list(analysis = 1:4, assessment = integer()) - - split <- make_splits(indices, df) - - expect_identical(split$out_id, integer()) - expect_identical(assessment(split), df[0, , drop = FALSE]) -}) - -test_that("cannot create a split with an empty analysis set", { - df <- data.frame(x = c(1, 2, 3, 4)) - indices <- list(analysis = integer(), assessment = 1:4) - - expect_error(make_splits(indices, df), "At least one row") -}) - -test_that("create a split from training and testing dataframes", { - training <- tibble(x = c(1, 2, 3, 4)) - testing <- tibble(x = c(5, 6)) - - split <- make_splits(training, testing) - expect_identical(analysis(split), training) - expect_identical(assessment(split), testing) -}) - -test_that("can create a split from empty testing dataframe", { - training <- tibble(x = c(1, 2, 3, 4)) - testing <- tibble() - - split <- make_splits(training, testing) - expect_identical(split$out_id, integer()) - expect_identical(analysis(split), training) -}) - -test_that("cannot create a split from empty training dataframe", { - training <- tibble() - testing <- tibble(x = c(5, 6)) - - expect_error( - make_splits(training, testing), - "The analysis set must contain at least one row." - ) -}) - -test_that("cannot create a split from dataframes with different columns", { - training <- tibble(x = c(1, 2, 3, 4)) - testing <- tibble(y = c(5, 6)) - - expect_error( - make_splits(training, testing), - "The analysis and assessment sets must have" - ) -}) - -test_that("improper argument", { - expect_snapshot(error = TRUE, { - make_splits("potato") - }) -}) diff --git a/tests/testthat/test-strata.R b/tests/testthat/test-make_strata.R similarity index 100% rename from tests/testthat/test-strata.R rename to tests/testthat/test-make_strata.R diff --git a/tests/testthat/test-misc.R b/tests/testthat/test-misc.R index 7435bb36..6fdcda55 100644 --- a/tests/testthat/test-misc.R +++ b/tests/testthat/test-misc.R @@ -1,152 +1,71 @@ -test_that("reverse_splits is working", { - skip_if_not_installed("withr") +test_that("can create a split with an empty assessment set (#188)", { + df <- data.frame(x = c(1, 2, 3, 4)) + indices <- list(analysis = 1:4, assessment = integer()) - reversable_subclasses <- setdiff(names(rset_subclasses), "permutations") - reversable_subclasses <- rset_subclasses[reversable_subclasses] - for (x in reversable_subclasses) { + split <- make_splits(indices, df) - set.seed(123) - rev_x <- reverse_splits(x) - expect_identical(analysis(x$splits[[1]]), assessment(rev_x$splits[[1]])) - expect_identical(assessment(x$splits[[1]]), analysis(rev_x$splits[[1]])) - expect_identical(class(x), class(rev_x)) - expect_identical(class(x$splits[[1]]), class(rev_x$splits[[1]])) + expect_identical(split$out_id, integer()) + expect_identical(assessment(split), df[0, , drop = FALSE]) +}) - } +test_that("cannot create a split with an empty analysis set", { + df <- data.frame(x = c(1, 2, 3, 4)) + indices <- list(analysis = integer(), assessment = 1:4) - expect_snapshot( - reverse_splits(1), - error = TRUE - ) + expect_error(make_splits(indices, df), "At least one row") +}) - permutes <- permutations(mtcars, cyl) +test_that("create a split from training and testing dataframes", { + training <- tibble(x = c(1, 2, 3, 4)) + testing <- tibble(x = c(5, 6)) - expect_snapshot( - reverse_splits(permutes), - error = TRUE - ) + split <- make_splits(training, testing) + expect_identical(analysis(split), training) + expect_identical(assessment(split), testing) +}) - expect_snapshot( - reverse_splits(permutes$splits[[1]]), - error = TRUE - ) +test_that("can create a split from empty testing dataframe", { + training <- tibble(x = c(1, 2, 3, 4)) + testing <- tibble() + split <- make_splits(training, testing) + expect_identical(split$out_id, integer()) + expect_identical(analysis(split), training) }) -test_that("reshuffle_rset is working", { - skip_if_not_installed("withr") - # for `validation_split()` and variants - withr::local_options(lifecycle_verbosity = "quiet") - - supported_subclasses <- rset_subclasses[ - setdiff(names(rset_subclasses), c("manual_rset")) - ] - - # Reshuffling with the same seed, in the same order, - # should recreate the same objects - out <- withr::with_seed( - 123, - lapply( - supported_subclasses, - function(x) suppressWarnings(reshuffle_rset(x)) - ) - ) +test_that("cannot create a split from empty training dataframe", { + training <- tibble() + testing <- tibble(x = c(5, 6)) - for (i in seq_along(supported_subclasses)) { - expect_identical( - out[[i]], - supported_subclasses[[i]] - ) - } - - # Check to make sure that stratification, - # with non-default arguments, - # is supported by reshuffled_resample - - # Select any non-grouped function in rset_subclasses with a strata argument: - supports_strata <- purrr::map_lgl( - names(supported_subclasses), - ~ any(names(formals(.x)) == "strata") && !any(names(formals(.x)) == "group") - ) - supports_strata <- names(supported_subclasses)[supports_strata] - - for (i in seq_along(supports_strata)) { - # Fit those functions with non-default arguments: - set.seed(123) - resample <- do.call( - supports_strata[i], - list( - data = test_data(), - strata = "y", - breaks = 2, - pool = 0.2 - ) - ) - # Reshuffle them under the same seed to ensure they're identical - set.seed(123) - reshuffled_resample <- reshuffle_rset(resample) - expect_identical(resample, reshuffled_resample) - } - - # Select any grouped function in rset_subclasses with a strata argument: - grouped_strata <- purrr::map_lgl( - names(supported_subclasses), - ~ any(names(formals(.x)) == "strata") && any(names(formals(.x)) == "group") + expect_error( + make_splits(training, testing), + "The analysis set must contain at least one row." ) - grouped_strata <- names(supported_subclasses)[grouped_strata] +}) - set.seed(11) +test_that("cannot create a split from dataframes with different columns", { + training <- tibble(x = c(1, 2, 3, 4)) + testing <- tibble(y = c(5, 6)) - group_table <- tibble::tibble( - group = 1:100, - outcome = sample(c(rep(0, 89), rep(1, 11))) - ) - observation_table <- tibble::tibble( - group = sample(1:100, 5e4, replace = TRUE), - observation = 1:5e4 - ) - sample_data <- dplyr::full_join( - group_table, - observation_table, - by = "group", - multiple = "all" + expect_error( + make_splits(training, testing), + "The analysis and assessment sets must have" ) +}) - for (i in seq_along(grouped_strata)) { - # Fit those functions with non-default arguments: - set.seed(123) - resample <- suppressWarnings( - do.call( - grouped_strata[i], - list( - data = sample_data, - group = "group", - strata = "outcome", - pool = 0.2 - ) - ) - ) - # Reshuffle them under the same seed to ensure they're identical - set.seed(123) - reshuffled_resample <- reshuffle_rset(resample) - expect_identical(resample, reshuffled_resample) - } - - for (i in seq_along(non_random_classes)) { - expect_snapshot( - reshuffle_rset(rset_subclasses[[non_random_classes[[i]]]]) - ) - } - - resample <- vfold_cv(mtcars, strata = cyl) - attr(resample, "strata") <- TRUE - - expect_snapshot_error(reshuffle_rset(resample)) - - expect_snapshot_error(reshuffle_rset(rset_subclasses[["manual_rset"]])) - - expect_snapshot_error(reshuffle_rset(rset_subclasses[["manual_rset"]]$splits[[1]])) +test_that("improper argument", { + expect_snapshot(error = TRUE, { + make_splits("potato") + }) +}) +test_that("basic naming sequences", { + expect_equal(names0(2), c("x1", "x2")) + expect_equal(names0(2, "y"), c("y1", "y2")) + expect_equal( + names0(10), + c(paste0("x0", 1:9), "x10") + ) }) test_that("get_rsplit()", { diff --git a/tests/testthat/test-names.R b/tests/testthat/test-names.R deleted file mode 100644 index e8821fc6..00000000 --- a/tests/testthat/test-names.R +++ /dev/null @@ -1,8 +0,0 @@ -test_that("basic naming sequences", { - expect_equal(names0(2), c("x1", "x2")) - expect_equal(names0(2, "y"), c("y1", "y2")) - expect_equal( - names0(10), - c(paste0("x0", 1:9), "x10") - ) -}) diff --git a/tests/testthat/test-nesting.R b/tests/testthat/test-nested_cv.R similarity index 100% rename from tests/testthat/test-nesting.R rename to tests/testthat/test-nested_cv.R diff --git a/tests/testthat/test-reg_intervals.R b/tests/testthat/test-reg_intervals.R new file mode 100644 index 00000000..283fd37f --- /dev/null +++ b/tests/testthat/test-reg_intervals.R @@ -0,0 +1,51 @@ +test_that("regression intervals", { + skip_if_not_installed("broom") + skip_on_cran() + + expect_error( + { + set.seed(1) + int_1 <- reg_intervals(mpg ~ disp + wt, data = mtcars) + }, + regexp = NA + ) + + expect_equal( + names(int_1), + c("term", ".lower", ".estimate", ".upper", ".alpha", ".method") + ) + + expect_snapshot({ + skip_if(new_rng_snapshots) + set.seed(123) + int_2 <- reg_intervals( + mpg ~ disp + wt, + data = mtcars, + filter = term == "wt", + model_fn = "glm", + keep_reps = TRUE + ) + int_2 + }) + + expect_equal( + names(int_2), + c("term", ".lower", ".estimate", ".upper", ".alpha", ".method", ".replicates") + ) + expect_true(nrow(int_2) == 1) + expect_true(all(int_2$term == "wt")) + + + expect_error( + reg_intervals(mpg ~ disp + wt, data = mtcars, model_fn = "potato"), + "`model_fn` must be one of" + ) + expect_error( + reg_intervals(mpg ~ disp + wt, data = mtcars, type = "random"), + "`type` must be one of" + ) + expect_error( + reg_intervals(mpg ~ disp + wt, data = mtcars, alpha = "a"), + "must be a single numeric value" + ) +}) diff --git a/tests/testthat/test-reshuffle_rset.R b/tests/testthat/test-reshuffle_rset.R new file mode 100644 index 00000000..47412358 --- /dev/null +++ b/tests/testthat/test-reshuffle_rset.R @@ -0,0 +1,115 @@ +test_that("reshuffle_rset is working", { + skip_if_not_installed("withr") + # for `validation_split()` and variants + withr::local_options(lifecycle_verbosity = "quiet") + + supported_subclasses <- rset_subclasses[ + setdiff(names(rset_subclasses), c("manual_rset")) + ] + + # Reshuffling with the same seed, in the same order, + # should recreate the same objects + out <- withr::with_seed( + 123, + lapply( + supported_subclasses, + function(x) suppressWarnings(reshuffle_rset(x)) + ) + ) + + for (i in seq_along(supported_subclasses)) { + expect_identical( + out[[i]], + supported_subclasses[[i]] + ) + } + + # Check to make sure that stratification, + # with non-default arguments, + # is supported by reshuffled_resample + + # Select any non-grouped function in rset_subclasses with a strata argument: + supports_strata <- purrr::map_lgl( + names(supported_subclasses), + ~ any(names(formals(.x)) == "strata") && !any(names(formals(.x)) == "group") + ) + supports_strata <- names(supported_subclasses)[supports_strata] + + for (i in seq_along(supports_strata)) { + # Fit those functions with non-default arguments: + set.seed(123) + resample <- do.call( + supports_strata[i], + list( + data = test_data(), + strata = "y", + breaks = 2, + pool = 0.2 + ) + ) + # Reshuffle them under the same seed to ensure they're identical + set.seed(123) + reshuffled_resample <- reshuffle_rset(resample) + expect_identical(resample, reshuffled_resample) + } + + # Select any grouped function in rset_subclasses with a strata argument: + grouped_strata <- purrr::map_lgl( + names(supported_subclasses), + ~ any(names(formals(.x)) == "strata") && any(names(formals(.x)) == "group") + ) + grouped_strata <- names(supported_subclasses)[grouped_strata] + + set.seed(11) + + group_table <- tibble::tibble( + group = 1:100, + outcome = sample(c(rep(0, 89), rep(1, 11))) + ) + observation_table <- tibble::tibble( + group = sample(1:100, 5e4, replace = TRUE), + observation = 1:5e4 + ) + sample_data <- dplyr::full_join( + group_table, + observation_table, + by = "group", + multiple = "all" + ) + + for (i in seq_along(grouped_strata)) { + # Fit those functions with non-default arguments: + set.seed(123) + resample <- suppressWarnings( + do.call( + grouped_strata[i], + list( + data = sample_data, + group = "group", + strata = "outcome", + pool = 0.2 + ) + ) + ) + # Reshuffle them under the same seed to ensure they're identical + set.seed(123) + reshuffled_resample <- reshuffle_rset(resample) + expect_identical(resample, reshuffled_resample) + } + + for (i in seq_along(non_random_classes)) { + expect_snapshot( + reshuffle_rset(rset_subclasses[[non_random_classes[[i]]]]) + ) + } + + resample <- vfold_cv(mtcars, strata = cyl) + attr(resample, "strata") <- TRUE + + expect_snapshot_error(reshuffle_rset(resample)) + + expect_snapshot_error(reshuffle_rset(rset_subclasses[["manual_rset"]])) + + expect_snapshot_error(reshuffle_rset(rset_subclasses[["manual_rset"]]$splits[[1]])) + +}) diff --git a/tests/testthat/test-reverse_splits.R b/tests/testthat/test-reverse_splits.R new file mode 100644 index 00000000..0965e367 --- /dev/null +++ b/tests/testthat/test-reverse_splits.R @@ -0,0 +1,34 @@ +test_that("reverse_splits is working", { + skip_if_not_installed("withr") + + reversable_subclasses <- setdiff(names(rset_subclasses), "permutations") + reversable_subclasses <- rset_subclasses[reversable_subclasses] + for (x in reversable_subclasses) { + + set.seed(123) + rev_x <- reverse_splits(x) + expect_identical(analysis(x$splits[[1]]), assessment(rev_x$splits[[1]])) + expect_identical(assessment(x$splits[[1]]), analysis(rev_x$splits[[1]])) + expect_identical(class(x), class(rev_x)) + expect_identical(class(x$splits[[1]]), class(rev_x$splits[[1]])) + + } + + expect_snapshot( + reverse_splits(1), + error = TRUE + ) + + permutes <- permutations(mtcars, cyl) + + expect_snapshot( + reverse_splits(permutes), + error = TRUE + ) + + expect_snapshot( + reverse_splits(permutes$splits[[1]]), + error = TRUE + ) + +}) diff --git a/tests/testthat/test-rolling.R b/tests/testthat/test-rolling_origin.R similarity index 100% rename from tests/testthat/test-rolling.R rename to tests/testthat/test-rolling_origin.R diff --git a/tests/testthat/test-validation.R b/tests/testthat/test-validation_split.R similarity index 100% rename from tests/testthat/test-validation.R rename to tests/testthat/test-validation_split.R