From ea256abfdd8706e7e508f9dca81e67f2d5854b8e Mon Sep 17 00:00:00 2001 From: ddueber Date: Thu, 13 Nov 2025 15:25:24 -0500 Subject: [PATCH] Change uniroot to uniroot.integer for target_param == "n" When searching for a sample size, uniroot wastes HUGE amounts of time narrowing down the fractional part of the solution instead of just stopping when it finds the integer part of the solution. uniroot.integer from the ssanv package will only try integer values. In my tests, this leads to about a 10x speedup. If you don't want to rely on ssanv, all uniroot.integer does is a simple binary search, which is easy enough to code. --- R/logistic_regression_power.R | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/R/logistic_regression_power.R b/R/logistic_regression_power.R index 42907b2..5b39bd3 100644 --- a/R/logistic_regression_power.R +++ b/R/logistic_regression_power.R @@ -111,7 +111,11 @@ logistic_regression_power <- function(r_partial = NULL, n = NULL, power = NULL, } search_interval <- if(target_param == "n") c(n_predictors + 5, 100000) else c(0.01, 0.99) solution <- tryCatch( - stats::uniroot(power_diff_func, interval = search_interval), + if (target_param == "n") { + ssanv::uniroot.integer(power_diff_func, interval = search_interval, step.power = 15) + } else { + stats::uniroot(power_diff_func, interval = search_interval) + }, error = function(e) stop("Could not find a solution. The effect size may be too small or power too high.") ) result <- list(value = solution$root)