From b8dcaf0d06272d346764d109f0f2d03ad069d2db Mon Sep 17 00:00:00 2001 From: Hyunsu Cho Date: Tue, 9 Jul 2024 23:04:12 -0700 Subject: [PATCH 1/2] [R] Gracefully handle deprecated parameters --- R-package/R/utils.R | 12 ++++++++++-- R-package/R/xgb.cv.R | 4 ++-- R-package/R/xgb.train.R | 4 ++-- R-package/R/xgboost.R | 3 ++- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/R-package/R/utils.R b/R-package/R/utils.R index 69f358751dc8..0ce8feee008d 100644 --- a/R-package/R/utils.R +++ b/R-package/R/utils.R @@ -37,7 +37,9 @@ NVL <- function(x, val) { # Merges booster params with whatever is provided in ... # plus runs some checks -check.booster.params <- function(params, ...) { +# Note: deprecated params in deprecated_params will be excluded from the +# final list of merged params +check.booster.params <- function(params, deprecated_params, ...) { if (!identical(class(params), "list")) stop("params must be a list") @@ -50,6 +52,7 @@ check.booster.params <- function(params, ...) { if (length(intersect(names(params), names(dot_params))) > 0) stop("Same parameters in 'params' and in the call are not allowed. Please check your 'params' list.") + dot_params <- within(dot_params, rm(list=deprecated_params)) # Exclude deprecated params params <- c(params, dot_params) # providing a parameter multiple times makes sense only for 'eval_metric' @@ -499,6 +502,7 @@ colnames(depr_par_lut) <- c('old', 'new') # Checks the dot-parameters for deprecated names # (including partial matching), gives a deprecation warning, # and sets new parameters to the old parameters' values within its parent frame. +# Also returns the list of old parameters that were passed in. # WARNING: has side-effects check.deprecation <- function(..., env = parent.frame()) { pars <- list(...) @@ -511,6 +515,8 @@ check.deprecation <- function(..., env = parent.frame()) { idx_lut <- all_match[idx_pars] # which of idx_lut were the exact matches? ex_match <- depr_par_lut[idx_lut, 1] %in% names(pars) + # List of deprecated parameters, to be returned + ret_deprecated_pars <- character(length(idx_pars)) for (i in seq_along(idx_pars)) { pars_par <- names(pars)[idx_pars[i]] old_par <- depr_par_lut[idx_lut[i], 1] @@ -519,8 +525,10 @@ check.deprecation <- function(..., env = parent.frame()) { warning("'", pars_par, "' was partially matched to '", old_par, "'") } .Deprecated(new_par, old = old_par, package = 'xgboost') + ret_deprecated_pars[i] <- old_par if (new_par != 'NULL') { - eval(parse(text = paste(new_par, '<-', pars[[pars_par]])), envir = env) + assign(new_par, pars[[pars_par]], envir = env) } } + return(ret_deprecated_pars) } diff --git a/R-package/R/xgb.cv.R b/R-package/R/xgb.cv.R index 880fd56974bc..020fc6389ec0 100644 --- a/R-package/R/xgb.cv.R +++ b/R-package/R/xgb.cv.R @@ -145,13 +145,13 @@ xgb.cv <- function(params = list(), data, nrounds, nfold, verbose = TRUE, print_every_n = 1L, early_stopping_rounds = NULL, maximize = NULL, callbacks = list(), ...) { - check.deprecation(...) + deprecated_params <- check.deprecation(...) stopifnot(inherits(data, "xgb.DMatrix")) if (inherits(data, "xgb.DMatrix") && .Call(XGCheckNullPtr_R, data)) { stop("'data' is an invalid 'xgb.DMatrix' object. Must be constructed again.") } - params <- check.booster.params(params, ...) + params <- check.booster.params(params, deprecated_params, ...) # TODO: should we deprecate the redundant 'metrics' parameter? for (m in metrics) params <- c(params, list("eval_metric" = m)) diff --git a/R-package/R/xgb.train.R b/R-package/R/xgb.train.R index 30bf1f1ea149..c35ba04f87ea 100644 --- a/R-package/R/xgb.train.R +++ b/R-package/R/xgb.train.R @@ -341,9 +341,9 @@ xgb.train <- function(params = list(), data, nrounds, evals = list(), save_period = NULL, save_name = "xgboost.model", xgb_model = NULL, callbacks = list(), ...) { - check.deprecation(...) + deprecated_params <- check.deprecation(...) - params <- check.booster.params(params, ...) + params <- check.booster.params(params, deprecated_params, ...) check.custom.obj() check.custom.eval() diff --git a/R-package/R/xgboost.R b/R-package/R/xgboost.R index a1d37358162c..22f44d7da915 100644 --- a/R-package/R/xgboost.R +++ b/R-package/R/xgboost.R @@ -9,7 +9,8 @@ xgboost <- function(data = NULL, label = NULL, missing = NA, weight = NULL, early_stopping_rounds = NULL, maximize = NULL, save_period = NULL, save_name = "xgboost.model", xgb_model = NULL, callbacks = list(), ...) { - merged <- check.booster.params(params, ...) + deprecated_params <- check.deprecation(...) + merged <- check.booster.params(params, deprecated_params, ...) dtrain <- xgb.get.DMatrix( data = data, label = label, From 594b6f983332d5a4da7bfd5f941545ded14f8b87 Mon Sep 17 00:00:00 2001 From: Hyunsu Cho Date: Wed, 10 Jul 2024 00:09:09 -0700 Subject: [PATCH 2/2] Fix formatting --- R-package/R/utils.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R-package/R/utils.R b/R-package/R/utils.R index 0ce8feee008d..4744d2366ca2 100644 --- a/R-package/R/utils.R +++ b/R-package/R/utils.R @@ -52,7 +52,7 @@ check.booster.params <- function(params, deprecated_params, ...) { if (length(intersect(names(params), names(dot_params))) > 0) stop("Same parameters in 'params' and in the call are not allowed. Please check your 'params' list.") - dot_params <- within(dot_params, rm(list=deprecated_params)) # Exclude deprecated params + dot_params <- within(dot_params, rm(list = deprecated_params)) # Exclude deprecated params params <- c(params, dot_params) # providing a parameter multiple times makes sense only for 'eval_metric'