From 0521230678a6ec57d208860b36fbd00c06363641 Mon Sep 17 00:00:00 2001 From: Marly Gotti Date: Mon, 23 Feb 2026 18:16:45 -0500 Subject: [PATCH 1/2] Fix score percentile clamping for out-of-range values --- NEWS.md | 1 + R/helpers.R | 4 ++-- tests/testthat/test-isolation-score.R | 15 +++++++++++++++ tests/testthat/test-pca-score.R | 11 +++++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 102ad4e..03e1e70 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,6 @@ # applicable (development version) +- Fixed percentile clamping in `score()` outputs so extreme out-of-range values use the correct percentile scale (e.g. `100` instead of `1` on `*_pctl` / `score_pctl` columns). - Improved `autoplot.apd_pca()` selector handling to fail early with a clear error when `...` selectors match no columns. - Modernized package code, tests, and vignettes to use base R pipes (`|>`) and replaced superseded tidyverse helpers (`pivot_longer()`, `across()`, and `rename_with()`). - Updated tests to use stricter modern expectations, including replacing success-path `expect_error(..., regexp = NA)` checks with `expect_no_error()`. diff --git a/R/helpers.R b/R/helpers.R index a9d360f..3d681e6 100644 --- a/R/helpers.R +++ b/R/helpers.R @@ -57,7 +57,7 @@ get_inv <- function(X) { # Get percentile for new samples get_new_percentile <- function(ref, x_new, grid) { res <- approx(ref, grid, xout = x_new)$y - res[x_new < min(ref, na.rm = TRUE)] <- 0 - res[x_new > max(ref, na.rm = TRUE)] <- 1 + res[x_new < min(ref, na.rm = TRUE)] <- min(grid, na.rm = TRUE) + res[x_new > max(ref, na.rm = TRUE)] <- max(grid, na.rm = TRUE) res } diff --git a/tests/testthat/test-isolation-score.R b/tests/testthat/test-isolation-score.R index 5144926..6bb40bf 100644 --- a/tests/testthat/test-isolation-score.R +++ b/tests/testthat/test-isolation-score.R @@ -16,3 +16,18 @@ test_that("scoring isolation forests", { raw_res <- unname(predict(res_df$model, cells_te)) expect_equal(raw_res, score_te$score) }) + +test_that("isolation score percentiles clamp to 100 for extreme scores", { + skip_if_not_installed("isotree") + + mod <- apd_isolation(iris[, 1:4], nthreads = 1) + new_data <- tibble::tibble( + Sepal.Length = 1e9, + Sepal.Width = 1e9, + Petal.Length = 1e9, + Petal.Width = 1e9 + ) + + res <- score(mod, new_data) + expect_equal(res$score_pctl, 100) +}) diff --git a/tests/testthat/test-pca-score.R b/tests/testthat/test-pca-score.R index b4e311a..28e6952 100644 --- a/tests/testthat/test-pca-score.R +++ b/tests/testthat/test-pca-score.R @@ -78,3 +78,14 @@ test_that("`score_apd_pca_bridge` output is correct", { expected ) }) + +test_that("`score` percentiles clamp to 100 for extreme PCA values", { + model <- apd_pca(mtcars) + predictors <- mtcars[1, , drop = FALSE] + predictors[] <- predictors[] * 1000 + + pctls <- score(model, predictors) |> + dplyr::select(dplyr::ends_with("_pctl")) + + expect_true(all(unlist(pctls, use.names = FALSE) == 100)) +}) From e7781af6adb9e8e87480c71cca210db5e16b00b7 Mon Sep 17 00:00:00 2001 From: Marly Gotti Date: Mon, 23 Feb 2026 18:40:23 -0500 Subject: [PATCH 2/2] Remove feature from NEWS.md. --- NEWS.md | 1 - 1 file changed, 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 03e1e70..102ad4e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,5 @@ # applicable (development version) -- Fixed percentile clamping in `score()` outputs so extreme out-of-range values use the correct percentile scale (e.g. `100` instead of `1` on `*_pctl` / `score_pctl` columns). - Improved `autoplot.apd_pca()` selector handling to fail early with a clear error when `...` selectors match no columns. - Modernized package code, tests, and vignettes to use base R pipes (`|>`) and replaced superseded tidyverse helpers (`pivot_longer()`, `across()`, and `rename_with()`). - Updated tests to use stricter modern expectations, including replacing success-path `expect_error(..., regexp = NA)` checks with `expect_no_error()`.