diff --git a/R/arguments.R b/R/arguments.R index 6b14401bb..6ff64c6d5 100644 --- a/R/arguments.R +++ b/R/arguments.R @@ -86,7 +86,7 @@ check_others <- function(args, obj, core_args) { #' #' @export set_args <- function(object, ...) { - the_dots <- list(...) + the_dots <- enquos(...) if (length(the_dots) == 0) stop("Please pass at least one named argument.", call. = FALSE) main_args <- names(object$args) diff --git a/R/boost_tree.R b/R/boost_tree.R index 034390d6b..e6c309cc1 100644 --- a/R/boost_tree.R +++ b/R/boost_tree.R @@ -22,7 +22,7 @@ #' } #' These arguments are converted to their specific names at the #' time that the model is fit. Other options and argument can be -#' set using the `others` argument. If left to their defaults +#' set using the `...` slot. If left to their defaults #' here (`NULL`), the values are taken from the underlying model #' functions. If parameters need to be modified, `update` can be used #' in lieu of recreating the object from scratch. @@ -30,8 +30,6 @@ #' @param mode A single character string for the type of model. #' Possible values for this model are "unknown", "regression", or #' "classification". -#' @param others A named list of arguments to be used by the -#' underlying models (e.g., `xgboost::xgb.train`, etc.). . #' @param mtry An number for the number (or proportion) of predictors that will #' be randomly sampled at each split when creating the tree models (`xgboost` #' only). @@ -48,8 +46,11 @@ #' @param sample_size An number for the number (or proportion) of data that is #' exposed to the fitting routine. For `xgboost`, the sampling is done at at #' each iteration while `C5.0` samples once during traning. -#' @param ... Used for method consistency. Any arguments passed to -#' the ellipses will result in an error. Use `others` instead. +#' @param ... Other arguments to pass to the specific engine's +#' model fit function (see the Engine Details section below). This +#' should not include arguments defined by the main parameters to +#' this function. For the `update` function, the ellipses can +#' contain the primary arguments or any others. #' @details #' The data given to the function are not saved and are only used #' to determine the _mode_ of the model. For `boost_tree`, the @@ -62,12 +63,15 @@ #' \item \pkg{Spark}: `"spark"` #' } #' -#' Main parameter arguments (and those in `others`) can avoid +#' Main parameter arguments (and those in `...`) can avoid #' evaluation until the underlying function is executed by wrapping the #' argument in [rlang::expr()] (e.g. `mtry = expr(floor(sqrt(p)))`). #' +#' +#' @section Engine Details: +#' #' Engines may have pre-set default arguments when executing the -#' model fit call. These can be changed by using the `others` +#' model fit call. These can be changed by using the `...` #' argument to pass in the preferred values. For this type of #' model, the template of the fit calls are: #' @@ -114,13 +118,18 @@ boost_tree <- function(mode = "unknown", - ..., mtry = NULL, trees = NULL, min_n = NULL, tree_depth = NULL, learn_rate = NULL, loss_reduction = NULL, sample_size = NULL, - others = list()) { - check_empty_ellipse(...) + ...) { + others <- enquos(...) + mtry <- enquo(mtry) + trees <- enquo(trees) + min_n <- enquo(min_n) + learn_rate <- enquo(learn_rate) + loss_reduction <- enquo(loss_reduction) + sample_size <- enquo(sample_size) if (!(mode %in% boost_tree_modes)) stop("`mode` should be one of: ", @@ -184,10 +193,15 @@ update.boost_tree <- mtry = NULL, trees = NULL, min_n = NULL, tree_depth = NULL, learn_rate = NULL, loss_reduction = NULL, sample_size = NULL, - others = list(), fresh = FALSE, ...) { - check_empty_ellipse(...) + others <- enquos(...) + mtry <- enquo(mtry) + trees <- enquo(trees) + min_n <- enquo(min_n) + learn_rate <- enquo(learn_rate) + loss_reduction <- enquo(loss_reduction) + sample_size <- enquo(sample_size) args <- list( mtry = mtry, trees = trees, min_n = min_n, tree_depth = tree_depth, diff --git a/R/linear_reg.R b/R/linear_reg.R index d2aed4342..c04ba78f3 100644 --- a/R/linear_reg.R +++ b/R/linear_reg.R @@ -12,25 +12,19 @@ #' } #' These arguments are converted to their specific names at the #' time that the model is fit. Other options and argument can be -#' set using the `others` argument. If left to their defaults +#' set using the `...` slot. If left to their defaults #' here (`NULL`), the values are taken from the underlying model #' functions. If parameters need to be modified, `update` can be used #' in lieu of recreating the object from scratch. +#' @inheritParams boost_tree #' @param mode A single character string for the type of model. #' The only possible value for this model is "regression". -#' @param others A named list of arguments to be used by the -#' underlying models (e.g., `stats::lm`, -#' `rstanarm::stan_glm`, etc.). These are not evaluated -#' until the model is fit and will be substituted into the model -#' fit expression. #' @param penalty An non-negative number representing the #' total amount of regularization (`glmnet` and `spark` only). #' @param mixture A number between zero and one (inclusive) that #' represents the proportion of regularization that is used for the #' L2 penalty (i.e. weight decay, or ridge regression) versus L1 #' (the lasso) (`glmnet` and `spark` only). -#' @param ... Used for S3 method consistency. Any arguments passed to -#' the ellipses will result in an error. Use `others` instead. #' #' @details #' The data given to the function are not saved and are only used @@ -45,8 +39,10 @@ #' \item \pkg{Spark}: `"spark"` #' } #' +#' @section Engine Details: +#' #' Engines may have pre-set default arguments when executing the -#' model fit call. These can be changed by using the `others` +#' model fit call. These can be changed by using the `...` #' argument to pass in the preferred values. For this type of #' model, the template of the fit calls are: #' @@ -105,11 +101,13 @@ #' @importFrom purrr map_lgl linear_reg <- function(mode = "regression", - ..., penalty = NULL, mixture = NULL, - others = list()) { - check_empty_ellipse(...) + ...) { + others <- enquos(...) + penalty <- enquo(penalty) + mixture <- enquo(mixture) + if (!(mode %in% linear_reg_modes)) stop( "`mode` should be one of: ", @@ -121,7 +119,7 @@ linear_reg <- stop("The amount of regularization should be >= 0", call. = FALSE) if (is.numeric(mixture) && (mixture < 0 | mixture > 1)) stop("The mixture proportion should be within [0,1]", call. = FALSE) - if (length(mixture) > 1) + if (is.numeric(mixture) && length(mixture) > 1) stop("Only one value of `mixture` is allowed.", call. = FALSE) args <- list(penalty = penalty, mixture = mixture) @@ -156,11 +154,8 @@ print.linear_reg <- function(x, ...) { # ------------------------------------------------------------------------------ -#' @inheritParams linear_reg +#' @inheritParams update.boost_tree #' @param object A linear regression model specification. -#' @param fresh A logical for whether the arguments should be -#' modified in-place of or replaced wholesale. -#' @return An updated model specification. #' @examples #' model <- linear_reg(penalty = 10, mixture = 0.1) #' model @@ -172,10 +167,11 @@ print.linear_reg <- function(x, ...) { update.linear_reg <- function(object, penalty = NULL, mixture = NULL, - others = list(), fresh = FALSE, ...) { - check_empty_ellipse(...) + others <- enquos(...) + penalty <- enquo(penalty) + mixture <- enquo(mixture) if (is.numeric(penalty) && penalty < 0) stop("The amount of regularization should be >= 0", call. = FALSE) diff --git a/R/logistic_reg.R b/R/logistic_reg.R index 7051b46a6..7533c916c 100644 --- a/R/logistic_reg.R +++ b/R/logistic_reg.R @@ -12,25 +12,19 @@ #' } #' These arguments are converted to their specific names at the #' time that the model is fit. Other options and argument can be -#' set using the `others` argument. If left to their defaults +#' set using the `...` slot. If left to their defaults #' here (`NULL`), the values are taken from the underlying model #' functions. If parameters need to be modified, `update` can be used #' in lieu of recreating the object from scratch. +#' @inheritParams boost_tree #' @param mode A single character string for the type of model. #' The only possible value for this model is "classification". -#' @param others A named list of arguments to be used by the -#' underlying models (e.g., `stats::glm`, -#' `rstanarm::stan_glm`, etc.). These are not evaluated -#' until the model is fit and will be substituted into the model -#' fit expression. #' @param penalty An non-negative number representing the #' total amount of regularization (`glmnet` and `spark` only). #' @param mixture A number between zero and one (inclusive) that #' represents the proportion of regularization that is used for the #' L2 penalty (i.e. weight decay, or ridge regression) versus L1 #' (the lasso) (`glmnet` and `spark` only). -#' @param ... Used for S3 method consistency. Any arguments passed to -#' the ellipses will result in an error. Use `others` instead. #' @details #' For `logistic_reg`, the mode will always be "classification". #' @@ -42,8 +36,10 @@ #' \item \pkg{Spark}: `"spark"` #' } #' +#' @section Engine Details: +#' #' Engines may have pre-set default arguments when executing the -#' model fit call. These can be changed by using the `others` +#' model fit call. These can be changed by using the `...` #' argument to pass in the preferred values. For this type of #' model, the template of the fit calls are: #' @@ -103,11 +99,13 @@ #' @importFrom purrr map_lgl logistic_reg <- function(mode = "classification", - ..., penalty = NULL, mixture = NULL, - others = list()) { - check_empty_ellipse(...) + ...) { + others <- enquos(...) + penalty <- enquo(penalty) + mixture <- enquo(mixture) + if (!(mode %in% logistic_reg_modes)) stop( "`mode` should be one of: ", @@ -152,11 +150,8 @@ print.logistic_reg <- function(x, ...) { # ------------------------------------------------------------------------------ -#' @inheritParams logistic_reg +#' @inheritParams update.boost_tree #' @param object A logistic regression model specification. -#' @param fresh A logical for whether the arguments should be -#' modified in-place of or replaced wholesale. -#' @return An updated model specification. #' @examples #' model <- logistic_reg(penalty = 10, mixture = 0.1) #' model @@ -168,10 +163,11 @@ print.logistic_reg <- function(x, ...) { update.logistic_reg <- function(object, penalty = NULL, mixture = NULL, - others = list(), fresh = FALSE, ...) { - check_empty_ellipse(...) + others <- enquos(...) + penalty <- enquo(penalty) + mixture <- enquo(mixture) if (is.numeric(penalty) && penalty < 0) stop("The amount of regularization should be >= 0", call. = FALSE) diff --git a/R/logistic_reg_data.R b/R/logistic_reg_data.R index 707d5a4c4..fb81e3353 100644 --- a/R/logistic_reg_data.R +++ b/R/logistic_reg_data.R @@ -30,7 +30,7 @@ logistic_reg_glm_data <- func = c(pkg = "stats", fun = "glm"), defaults = list( - family = expr(binomial) + family = expr(stats::binomial) ) ), classes = list( @@ -151,7 +151,7 @@ logistic_reg_stan_data <- func = c(pkg = "rstanarm", fun = "stan_glm"), defaults = list( - family = expr(binomial) + family = expr(stats::binomial) ) ), classes = list( diff --git a/R/mars.R b/R/mars.R index dbaa8e381..cf153d139 100644 --- a/R/mars.R +++ b/R/mars.R @@ -17,26 +17,20 @@ #' } #' These arguments are converted to their specific names at the #' time that the model is fit. Other options and argument can be -#' set using the `others` argument. If left to their defaults +#' set using the `...` slot. If left to their defaults #' here (`NULL`), the values are taken from the underlying model #' functions. If parameters need to be modified, `update` can be used #' in lieu of recreating the object from scratch. #' +#' @inheritParams boost_tree #' @param mode A single character string for the type of model. #' Possible values for this model are "unknown", "regression", or #' "classification". -#' @param others A named list of arguments to be used by the -#' underlying models (e.g., `earth::earth`, etc.). If the outcome is a factor -#' and `mode = "classification"`, `others` can include the `glm` argument to -#' `earth::earth`. If this argument is not passed, it will be added prior to -#' the fitting occurs. #' @param num_terms The number of features that will be retained in the #' final model, including the intercept. #' @param prod_degree The highest possible interaction degree. #' @param prune_method The pruning method. -#' @param ... Used for method consistency. Any arguments passed to -#' the ellipses will result in an error. Use `others` instead. -#' @details Main parameter arguments (and those in `others`) can avoid +#' @details Main parameter arguments (and those in `...`) can avoid #' evaluation until the underlying function is executed by wrapping the #' argument in [rlang::expr()]. #' @@ -46,8 +40,10 @@ #' \item \pkg{R}: `"earth"` #' } #' +#' @section Engine Details: +#' #' Engines may have pre-set default arguments when executing the -#' model fit call. These can be changed by using the `others` +#' model fit call. These can be changed by using the `...` #' argument to pass in the preferred values. For this type of #' model, the template of the fit calls are: #' @@ -71,10 +67,12 @@ mars <- function(mode = "unknown", - ..., num_terms = NULL, prod_degree = NULL, prune_method = NULL, - others = list()) { - check_empty_ellipse(...) + ...) { + others <- enquos(...) + num_terms <- enquo(num_terms) + prod_degree <- enquo(prod_degree) + prune_method <- enquo(prune_method) if (!(mode %in% mars_modes)) stop("`mode` should be one of: ", @@ -87,7 +85,7 @@ mars <- stop("`num_terms` should be >= 1", call. = FALSE) if (!is_varying(prune_method) && !is.null(prune_method) && - !is.character(prune_method)) + is.character(prune_method)) stop("`prune_method` should be a single string value", call. = FALSE) args <- list(num_terms = num_terms, @@ -118,11 +116,8 @@ print.mars <- function(x, ...) { # ------------------------------------------------------------------------------ #' @export -#' @inheritParams mars +#' @inheritParams update.boost_tree #' @param object A MARS model specification. -#' @param fresh A logical for whether the arguments should be -#' modified in-place of or replaced wholesale. -#' @return An updated model specification. #' @examples #' model <- mars(num_terms = 10, prune_method = "none") #' model @@ -134,10 +129,12 @@ print.mars <- function(x, ...) { update.mars <- function(object, num_terms = NULL, prod_degree = NULL, prune_method = NULL, - others = list(), fresh = FALSE, ...) { - check_empty_ellipse(...) + others <- enquos(...) + num_terms <- enquo(num_terms) + prod_degree <- enquo(prod_degree) + prune_method <- enquo(prune_method) args <- list(num_terms = num_terms, prod_degree = prod_degree, diff --git a/R/mlp.R b/R/mlp.R index e4c3df660..8934318dd 100644 --- a/R/mlp.R +++ b/R/mlp.R @@ -18,7 +18,7 @@ #' #' These arguments are converted to their specific names at the #' time that the model is fit. Other options and argument can be -#' set using the `others` argument. If left to their defaults +#' set using the `...` slot. If left to their defaults #' here (see above), the values are taken from the underlying model #' functions. One exception is `hidden_units` when `nnet::nnet` is used; that #' function's `size` argument has no default so a value of 5 units will be @@ -26,13 +26,11 @@ #' `nnet::nnet` will be set to `TRUE` when a regression model is created. #' If parameters need to be modified, `update` can be used #' in lieu of recreating the object from scratch. - +#' +#' @inheritParams boost_tree #' @param mode A single character string for the type of model. #' Possible values for this model are "unknown", "regression", or #' "classification". -#' @param others A named list of arguments to be used by the -#' underlying models (e.g., `nnet::nnet`, -#' `keras::fit`, `keras::compile`, etc.). . #' @param hidden_units An integer for the number of units in the hidden model. #' @param penalty A non-negative numeric value for the amount of weight #' decay. @@ -44,8 +42,6 @@ #' function between the hidden and output layers is automatically set to either #' "linear" or "softmax" depending on the type of outcome. Possible values are: #' "linear", "softmax", "relu", and "elu" -#' @param ... Used for method consistency. Any arguments passed to -#' the ellipses will result in an error. Use `others` instead. #' @details #' #' The model can be created using the `fit()` function using the @@ -55,15 +51,17 @@ #' \item \pkg{keras}: `"keras"` #' } #' -#' Main parameter arguments (and those in `others`) can avoid +#' Main parameter arguments (and those in `...`) can avoid #' evaluation until the underlying function is executed by wrapping the #' argument in [rlang::expr()] (e.g. `hidden_units = expr(num_preds * 2)`). #' #' An error is thrown if both `penalty` and `dropout` are specified for #' `keras` models. #' +#' @section Engine Details: +#' #' Engines may have pre-set default arguments when executing the -#' model fit call. These can be changed by using the `others` +#' model fit call. These can be changed by using the `...` #' argument to pass in the preferred values. For this type of #' model, the template of the fit calls are: #' @@ -93,11 +91,16 @@ mlp <- function(mode = "unknown", - ..., hidden_units = NULL, penalty = NULL, dropout = NULL, epochs = NULL, activation = NULL, - others = list()) { - check_empty_ellipse(...) + ...) { + others <- enquos(...) + hidden_units <- enquo(hidden_units) + penalty <- enquo(penalty) + dropout <- enquo(dropout) + epochs <- enquo(epochs) + activation <- enquo(activation) + act_funs <- c("linear", "softmax", "relu", "elu") if (is.numeric(hidden_units)) @@ -157,11 +160,8 @@ print.mlp <- function(x, ...) { #' in lieu of recreating the object from scratch. #' #' @export -#' @inheritParams mlp +#' @inheritParams update.boost_tree #' @param object A random forest model specification. -#' @param fresh A logical for whether the arguments should be -#' modified in-place of or replaced wholesale. -#' @return An updated model specification. #' @examples #' model <- mlp(hidden_units = 10, dropout = 0.30) #' model @@ -174,10 +174,14 @@ update.mlp <- function(object, hidden_units = NULL, penalty = NULL, dropout = NULL, epochs = NULL, activation = NULL, - others = list(), fresh = FALSE, ...) { - check_empty_ellipse(...) + others <- enquos(...) + hidden_units <- enquo(hidden_units) + penalty <- enquo(penalty) + dropout <- enquo(dropout) + epochs <- enquo(epochs) + activation <- enquo(activation) args <- list(hidden_units = hidden_units, penalty = penalty, dropout = dropout, epochs = epochs, activation = activation) @@ -209,8 +213,9 @@ update.mlp <- translate.mlp <- function(x, engine, ...) { if (engine == "nnet") { - if(is.null(x$args$hidden_units)) + if(isTRUE(is.null(quo_get_expr(x$args$hidden_units)))) { x$args$hidden_units <- 5 + } } x <- translate.default(x, engine, ...) diff --git a/R/multinom_reg.R b/R/multinom_reg.R index 6f079f167..a9542fa78 100644 --- a/R/multinom_reg.R +++ b/R/multinom_reg.R @@ -12,24 +12,19 @@ #' } #' These arguments are converted to their specific names at the #' time that the model is fit. Other options and argument can be -#' set using the `others` argument. If left to their defaults +#' set using the `...` slot. If left to their defaults #' here (`NULL`), the values are taken from the underlying model #' functions. If parameters need to be modified, `update` can be used #' in lieu of recreating the object from scratch. +#' @inheritParams boost_tree #' @param mode A single character string for the type of model. #' The only possible value for this model is "classification". -#' @param others A named list of arguments to be used by the -#' underlying models (e.g., `glmnet::glmnet` etc.). These are not evaluated -#' until the model is fit and will be substituted into the model -#' fit expression. #' @param penalty An non-negative number representing the #' total amount of regularization. #' @param mixture A number between zero and one (inclusive) that #' represents the proportion of regularization that is used for the #' L2 penalty (i.e. weight decay, or ridge regression) versus L1 #' (the lasso) (`glmnet` only). -#' @param ... Used for S3 method consistency. Any arguments passed to -#' the ellipses will result in an error. Use `others` instead. #' @details #' For `multinom_reg`, the mode will always be "classification". #' @@ -40,8 +35,10 @@ #' \item \pkg{Stan}: `"stan"` #' } #' +#' @section Engine Details: +#' #' Engines may have pre-set default arguments when executing the -#' model fit call. These can be changed by using the `others` +#' model fit call. These can be changed by using the `...` #' argument to pass in the preferred values. For this type of #' model, the template of the fit calls are: #' @@ -85,11 +82,13 @@ #' @importFrom purrr map_lgl multinom_reg <- function(mode = "classification", - ..., penalty = NULL, mixture = NULL, - others = list()) { - check_empty_ellipse(...) + ...) { + others <- enquos(...) + penalty <- enquo(penalty) + mixture <- enquo(mixture) + if (!(mode %in% multinom_reg_modes)) stop( "`mode` should be one of: ", @@ -134,11 +133,8 @@ print.multinom_reg <- function(x, ...) { # ------------------------------------------------------------------------------ -#' @inheritParams multinom_reg +#' @inheritParams update.boost_tree #' @param object A multinomial regression model specification. -#' @param fresh A logical for whether the arguments should be -#' modified in-place of or replaced wholesale. -#' @return An updated model specification. #' @examples #' model <- multinom_reg(penalty = 10, mixture = 0.1) #' model @@ -150,10 +146,11 @@ print.multinom_reg <- function(x, ...) { update.multinom_reg <- function(object, penalty = NULL, mixture = NULL, - others = list(), fresh = FALSE, ...) { - check_empty_ellipse(...) + others <- enquos(...) + penalty <- enquo(penalty) + mixture <- enquo(mixture) if (is.numeric(penalty) && penalty < 0) stop("The amount of regularization should be >= 0", call. = FALSE) diff --git a/R/nearest_neighbor.R b/R/nearest_neighbor.R index 499be4ea0..ef638cb3d 100644 --- a/R/nearest_neighbor.R +++ b/R/nearest_neighbor.R @@ -19,11 +19,11 @@ #' } #' These arguments are converted to their specific names at the #' time that the model is fit. Other options and argument can be -#' set using the `others` argument. If left to their defaults +#' set using the `...` slot. If left to their defaults #' here (`NULL`), the values are taken from the underlying model #' functions. If parameters need to be modified, `update()` can be used #' in lieu of recreating the object from scratch. -#' +#' @inheritParams boost_tree #' @param mode A single character string for the type of model. #' Possible values for this model are `"unknown"`, `"regression"`, or #' `"classification"`. @@ -39,14 +39,6 @@ #' @param dist_power A single number for the parameter used in #' calculating Minkowski distance. #' -#' @param others A named list of arguments to be used by the -#' underlying models (e.g., `kknn::train.kknn`). These are not evaluated -#' until the model is fit and will be substituted into the model -#' fit expression. -#' -#' @param ... Used for S3 method consistency. Any arguments passed to -#' the ellipses will result in an error. Use `others` instead. -#' #' @details #' The model can be created using the `fit()` function using the #' following _engines_: @@ -54,8 +46,10 @@ #' \item \pkg{R}: `"kknn"` #' } #' +#' @section Engine Details: +#' #' Engines may have pre-set default arguments when executing the -#' model fit call. These can be changed by using the `others` +#' model fit call. These can be changed by using the `...` #' argument to pass in the preferred values. For this type of #' model, the template of the fit calls are: #' @@ -77,13 +71,14 @@ #' #' @export nearest_neighbor <- function(mode = "unknown", - ..., neighbors = NULL, weight_func = NULL, dist_power = NULL, - others = list()) { - - check_empty_ellipse(...) + ...) { + others <- enquos(...) + neighbors <- enquo(neighbors) + weight_func <- enquo(weight_func) + dist_power <- enquo(dist_power) ## TODO: make a utility function here if (!(mode %in% nearest_neighbor_modes)) { @@ -132,15 +127,18 @@ print.nearest_neighbor <- function(x, ...) { # ------------------------------------------------------------------------------ #' @export +#' @inheritParams update.boost_tree update.nearest_neighbor <- function(object, neighbors = NULL, weight_func = NULL, dist_power = NULL, - others = list(), fresh = FALSE, ...) { - check_empty_ellipse(...) + others <- enquos(...) + neighbors <- enquo(neighbors) + weight_func <- enquo(weight_func) + dist_power <- enquo(dist_power) if(is.numeric(neighbors) && !positive_int_scalar(neighbors)) { stop("`neighbors` must be a length 1 positive integer.", call. = FALSE) diff --git a/R/rand_forest.R b/R/rand_forest.R index 53b01401b..6c89f4eb0 100644 --- a/R/rand_forest.R +++ b/R/rand_forest.R @@ -15,25 +15,21 @@ #' } #' These arguments are converted to their specific names at the #' time that the model is fit. Other options and argument can be -#' set using the `others` argument. If left to their defaults +#' set using the `...` slot. If left to their defaults #' here (`NULL`), the values are taken from the underlying model #' functions. If parameters need to be modified, `update` can be used #' in lieu of recreating the object from scratch. #' +#' @inheritParams boost_tree #' @param mode A single character string for the type of model. #' Possible values for this model are "unknown", "regression", or #' "classification". -#' @param others A named list of arguments to be used by the -#' underlying models (e.g., `ranger::ranger`, -#' `randomForest::randomForest`, etc.). . #' @param mtry An integer for the number of predictors that will #' be randomly sampled at each split when creating the tree models. #' @param trees An integer for the number of trees contained in #' the ensemble. #' @param min_n An integer for the minimum number of data points #' in a node that are required for the node to be split further. -#' @param ... Used for method consistency. Any arguments passed to -#' the ellipses will result in an error. Use `others` instead. #' @details #' The model can be created using the `fit()` function using the #' following _engines_: @@ -42,14 +38,16 @@ #' \item \pkg{Spark}: `"spark"` #' } #' -#' Main parameter arguments (and those in `others`) can avoid +#' Main parameter arguments (and those in `...`) can avoid #' evaluation until the underlying function is executed by wrapping the #' argument in [rlang::expr()] (e.g. `mtry = expr(floor(sqrt(p)))`). #' +#' @section Engine Details: +#' #' Engines may have pre-set default arguments when executing the -#' model fit call. These can be changed by using the `others` +#' model fit call. These can be changed by using the `...` #' argument to pass in the preferred values. For this type of -#' model, the template of the fit calls are: +#' model, the template of the fit calls are:: #' #' \pkg{ranger} classification #' @@ -144,11 +142,8 @@ print.rand_forest <- function(x, ...) { # ------------------------------------------------------------------------------ #' @export -#' @inheritParams rand_forest +#' @inheritParams update.boost_tree #' @param object A random forest model specification. -#' @param fresh A logical for whether the arguments should be -#' modified in-place of or replaced wholesale. -#' @return An updated model specification. #' @examples #' model <- rand_forest(mtry = 10, min_n = 3) #' model @@ -160,10 +155,12 @@ print.rand_forest <- function(x, ...) { update.rand_forest <- function(object, mtry = NULL, trees = NULL, min_n = NULL, - others = list(), fresh = FALSE, ...) { - check_empty_ellipse(...) + others <- enquos(...) + mtry <- enquo(mtry) + trees <- enquo(trees) + min_n <- enquo(min_n) args <- list(mtry = mtry, trees = trees, min_n = min_n) @@ -194,34 +191,42 @@ update.rand_forest <- translate.rand_forest <- function(x, engine, ...) { x <- translate.default(x, engine, ...) + # slightly cleaner code using + arg_vals <- x$method$fit$args + if (x$engine == "spark") { - if (x$mode == "unknown") + if (x$mode == "unknown") { stop( "For spark random forests models, the mode cannot be 'unknown' ", "if the specification is to be translated.", call. = FALSE ) - else - x$method$fit$args$type <- x$mode - - # See "Details" in ?ml_random_forest_classifier - if (is.numeric(x$method$fit$args$feature_subset_strategy)) - x$method$fit$args$feature_subset_strategy <- - paste(x$method$fit$args$feature_subset_strategy) + } else { + arg_vals$type <- x$mode + } + # See "Details" in ?ml_random_forest_classifier. `feature_subset_strategy` + # should be character even if it contains a number. + if (any(names(arg_vals) == "feature_subset_strategy") && + isTRUE(is.numeric(quo_get_expr(arg_vals$feature_subset_strategy)))) { + arg_vals$feature_subset_strategy <- + paste(quo_get_expr(arg_vals$feature_subset_strategy)) + } } # add checks to error trap or change things for this method if (x$engine == "ranger") { - if (any(names(x$method$fit$args) == "importance")) - if (is.logical(x$method$fit$args$importance)) + if (any(names(arg_vals) == "importance")) + if (isTRUE(is.logical(quo_get_expr(arg_vals$importance)))) stop("`importance` should be a character value. See ?ranger::ranger.", call. = FALSE) # unless otherwise specified, classification models are probability forests - if (x$mode == "classification" && !any(names(x$method$fit$args) == "probability")) - x$method$fit$args$probability <- TRUE + if (x$mode == "classification" && !any(names(arg_vals) == "probability")) + arg_vals$probability <- TRUE } + x$method$fit$args <- arg_vals + x } diff --git a/R/surv_reg.R b/R/surv_reg.R index 16ad84b70..5e391c191 100644 --- a/R/surv_reg.R +++ b/R/surv_reg.R @@ -9,7 +9,7 @@ #' } #' This argument is converted to its specific names at the #' time that the model is fit. Other options and argument can be -#' set using the `others` argument. If left to its default +#' set using the `...` slot. If left to its default #' here (`NULL`), the value is taken from the underlying model #' functions. #' @@ -30,16 +30,11 @@ #' \itemize{ #' \item \pkg{R}: `"flexsurv"` #' } +#' @inheritParams boost_tree #' @param mode A single character string for the type of model. #' The only possible value for this model is "regression". -#' @param others A named list of arguments to be used by the -#' underlying models (e.g., `flexsurv::flexsurvreg`). These are not evaluated -#' until the model is fit and will be substituted into the model -#' fit expression. #' @param dist A character string for the outcome distribution. "weibull" is #' the default. -#' @param ... Used for S3 method consistency. Any arguments passed to -#' the ellipses will result in an error. Use `others` instead. #' @seealso [varying()], [fit()], [survival::Surv()] #' @references Jackson, C. (2016). `flexsurv`: A Platform for Parametric Survival #' Modeling in R. _Journal of Statistical Software_, 70(8), 1 - 33. @@ -51,10 +46,11 @@ #' @export surv_reg <- function(mode = "regression", - ..., dist = NULL, - others = list()) { - check_empty_ellipse(...) + ...) { + others <- enquos(...) + dist <- enquo(dist) + if (!(mode %in% surv_reg_modes)) stop( "`mode` should be one of: ", @@ -98,11 +94,8 @@ print.surv_reg <- function(x, ...) { #' If parameters need to be modified, this function can be used #' in lieu of recreating the object from scratch. #' -#' @inheritParams surv_reg +#' @inheritParams update.boost_tree #' @param object A survival regression model specification. -#' @param fresh A logical for whether the arguments should be -#' modified in-place of or replaced wholesale. -#' @return An updated model specification. #' @examples #' model <- surv_reg(dist = "weibull") #' model @@ -113,10 +106,10 @@ print.surv_reg <- function(x, ...) { update.surv_reg <- function(object, dist = NULL, - others = list(), fresh = FALSE, ...) { - check_empty_ellipse(...) + others <- enquos(...) + dist <- enquo(dist) args <- list(dist = dist) diff --git a/man/boost_tree.Rd b/man/boost_tree.Rd index a7520d251..1e55def1d 100644 --- a/man/boost_tree.Rd +++ b/man/boost_tree.Rd @@ -5,23 +5,19 @@ \alias{update.boost_tree} \title{General Interface for Boosted Trees} \usage{ -boost_tree(mode = "unknown", ..., mtry = NULL, trees = NULL, +boost_tree(mode = "unknown", mtry = NULL, trees = NULL, min_n = NULL, tree_depth = NULL, learn_rate = NULL, - loss_reduction = NULL, sample_size = NULL, others = list()) + loss_reduction = NULL, sample_size = NULL, ...) \method{update}{boost_tree}(object, mtry = NULL, trees = NULL, min_n = NULL, tree_depth = NULL, learn_rate = NULL, - loss_reduction = NULL, sample_size = NULL, others = list(), - fresh = FALSE, ...) + loss_reduction = NULL, sample_size = NULL, fresh = FALSE, ...) } \arguments{ \item{mode}{A single character string for the type of model. Possible values for this model are "unknown", "regression", or "classification".} -\item{...}{Used for method consistency. Any arguments passed to -the ellipses will result in an error. Use \code{others} instead.} - \item{mtry}{An number for the number (or proportion) of predictors that will be randomly sampled at each split when creating the tree models (\code{xgboost} only).} @@ -45,8 +41,11 @@ to split further (\code{xgboost} only).} exposed to the fitting routine. For \code{xgboost}, the sampling is done at at each iteration while \code{C5.0} samples once during traning.} -\item{others}{A named list of arguments to be used by the -underlying models (e.g., \code{xgboost::xgb.train}, etc.). .} +\item{...}{Other arguments to pass to the specific engine's +model fit function (see the Engine Details section below). This +should not include arguments defined by the main parameters to +this function. For the \code{update} function, the ellipses can +contain the primary arguments or any others.} \item{object}{A boosted tree model specification.} @@ -77,7 +76,7 @@ to split further. } These arguments are converted to their specific names at the time that the model is fit. Other options and argument can be -set using the \code{others} argument. If left to their defaults +set using the \code{...} slot. If left to their defaults here (\code{NULL}), the values are taken from the underlying model functions. If parameters need to be modified, \code{update} can be used in lieu of recreating the object from scratch. @@ -94,12 +93,29 @@ following \emph{engines}: \item \pkg{Spark}: \code{"spark"} } -Main parameter arguments (and those in \code{others}) can avoid +Main parameter arguments (and those in \code{...}) can avoid evaluation until the underlying function is executed by wrapping the argument in \code{\link[rlang:expr]{rlang::expr()}} (e.g. \code{mtry = expr(floor(sqrt(p)))}). +} +\note{ +For models created using the spark engine, there are +several differences to consider. First, only the formula +interface to via \code{fit} is available; using \code{fit_xy} will +generate an error. Second, the predictions will always be in a +spark table format. The names will be the same as documented but +without the dots. Third, there is no equivalent to factor +columns in spark tables so class predictions are returned as +character columns. Fourth, to retain the model object for a new +R session (via \code{save}), the \code{model$fit} element of the \code{parsnip} +object should be serialized via \code{ml_save(object$fit)} and +separately saved to disk. In a new session, the object can be +reloaded and reattached to the \code{parsnip} object. +} +\section{Engine Details}{ + Engines may have pre-set default arguments when executing the -model fit call. These can be changed by using the \code{others} +model fit call. These can be changed by using the \code{...} argument to pass in the preferred values. For this type of model, the template of the fit calls are: @@ -123,20 +139,7 @@ model, the template of the fit calls are: \Sexpr[results=rd]{parsnip:::show_fit(parsnip:::boost_tree(mode = "regression"), "spark")} } -\note{ -For models created using the spark engine, there are -several differences to consider. First, only the formula -interface to via \code{fit} is available; using \code{fit_xy} will -generate an error. Second, the predictions will always be in a -spark table format. The names will be the same as documented but -without the dots. Third, there is no equivalent to factor -columns in spark tables so class predictions are returned as -character columns. Fourth, to retain the model object for a new -R session (via \code{save}), the \code{model$fit} element of the \code{parsnip} -object should be serialized via \code{ml_save(object$fit)} and -separately saved to disk. In a new session, the object can be -reloaded and reattached to the \code{parsnip} object. -} + \examples{ boost_tree(mode = "classification", trees = 20) # Parameters can be represented by a placeholder: diff --git a/man/linear_reg.Rd b/man/linear_reg.Rd index b108de728..e227b9796 100644 --- a/man/linear_reg.Rd +++ b/man/linear_reg.Rd @@ -5,19 +5,15 @@ \alias{update.linear_reg} \title{General Interface for Linear Regression Models} \usage{ -linear_reg(mode = "regression", ..., penalty = NULL, mixture = NULL, - others = list()) +linear_reg(mode = "regression", penalty = NULL, mixture = NULL, ...) \method{update}{linear_reg}(object, penalty = NULL, mixture = NULL, - others = list(), fresh = FALSE, ...) + fresh = FALSE, ...) } \arguments{ \item{mode}{A single character string for the type of model. The only possible value for this model is "regression".} -\item{...}{Used for S3 method consistency. Any arguments passed to -the ellipses will result in an error. Use \code{others} instead.} - \item{penalty}{An non-negative number representing the total amount of regularization (\code{glmnet} and \code{spark} only).} @@ -26,20 +22,17 @@ represents the proportion of regularization that is used for the L2 penalty (i.e. weight decay, or ridge regression) versus L1 (the lasso) (\code{glmnet} and \code{spark} only).} -\item{others}{A named list of arguments to be used by the -underlying models (e.g., \code{stats::lm}, -\code{rstanarm::stan_glm}, etc.). These are not evaluated -until the model is fit and will be substituted into the model -fit expression.} +\item{...}{Other arguments to pass to the specific engine's +model fit function (see the Engine Details section below). This +should not include arguments defined by the main parameters to +this function. For the \code{update} function, the ellipses can +contain the primary arguments or any others.} \item{object}{A linear regression model specification.} \item{fresh}{A logical for whether the arguments should be modified in-place of or replaced wholesale.} } -\value{ -An updated model specification. -} \description{ \code{linear_reg} is a way to generate a \emph{specification} of a model before fitting and allows the model to be created using @@ -53,7 +46,7 @@ the model. Note that this will be ignored for some engines. } These arguments are converted to their specific names at the time that the model is fit. Other options and argument can be -set using the \code{others} argument. If left to their defaults +set using the \code{...} slot. If left to their defaults here (\code{NULL}), the values are taken from the underlying model functions. If parameters need to be modified, \code{update} can be used in lieu of recreating the object from scratch. @@ -70,9 +63,26 @@ following \emph{engines}: \item \pkg{Stan}: \code{"stan"} \item \pkg{Spark}: \code{"spark"} } +} +\note{ +For models created using the spark engine, there are +several differences to consider. First, only the formula +interface to via \code{fit} is available; using \code{fit_xy} will +generate an error. Second, the predictions will always be in a +spark table format. The names will be the same as documented but +without the dots. Third, there is no equivalent to factor +columns in spark tables so class predictions are returned as +character columns. Fourth, to retain the model object for a new +R session (via \code{save}), the \code{model$fit} element of the \code{parsnip} +object should be serialized via \code{ml_save(object$fit)} and +separately saved to disk. In a new session, the object can be +reloaded and reattached to the \code{parsnip} object. +} +\section{Engine Details}{ + Engines may have pre-set default arguments when executing the -model fit call. These can be changed by using the \code{others} +model fit call. These can be changed by using the \code{...} argument to pass in the preferred values. For this type of model, the template of the fit calls are: @@ -109,20 +119,7 @@ these instances, the units are the original outcome and when distribution (or posterior predictive distribution as appropriate) is returned. } -\note{ -For models created using the spark engine, there are -several differences to consider. First, only the formula -interface to via \code{fit} is available; using \code{fit_xy} will -generate an error. Second, the predictions will always be in a -spark table format. The names will be the same as documented but -without the dots. Third, there is no equivalent to factor -columns in spark tables so class predictions are returned as -character columns. Fourth, to retain the model object for a new -R session (via \code{save}), the \code{model$fit} element of the \code{parsnip} -object should be serialized via \code{ml_save(object$fit)} and -separately saved to disk. In a new session, the object can be -reloaded and reattached to the \code{parsnip} object. -} + \examples{ linear_reg() # Parameters can be represented by a placeholder: diff --git a/man/logistic_reg.Rd b/man/logistic_reg.Rd index 1d4fc0533..d466ef684 100644 --- a/man/logistic_reg.Rd +++ b/man/logistic_reg.Rd @@ -5,19 +5,16 @@ \alias{update.logistic_reg} \title{General Interface for Logistic Regression Models} \usage{ -logistic_reg(mode = "classification", ..., penalty = NULL, - mixture = NULL, others = list()) +logistic_reg(mode = "classification", penalty = NULL, mixture = NULL, + ...) \method{update}{logistic_reg}(object, penalty = NULL, mixture = NULL, - others = list(), fresh = FALSE, ...) + fresh = FALSE, ...) } \arguments{ \item{mode}{A single character string for the type of model. The only possible value for this model is "classification".} -\item{...}{Used for S3 method consistency. Any arguments passed to -the ellipses will result in an error. Use \code{others} instead.} - \item{penalty}{An non-negative number representing the total amount of regularization (\code{glmnet} and \code{spark} only).} @@ -26,20 +23,17 @@ represents the proportion of regularization that is used for the L2 penalty (i.e. weight decay, or ridge regression) versus L1 (the lasso) (\code{glmnet} and \code{spark} only).} -\item{others}{A named list of arguments to be used by the -underlying models (e.g., \code{stats::glm}, -\code{rstanarm::stan_glm}, etc.). These are not evaluated -until the model is fit and will be substituted into the model -fit expression.} +\item{...}{Other arguments to pass to the specific engine's +model fit function (see the Engine Details section below). This +should not include arguments defined by the main parameters to +this function. For the \code{update} function, the ellipses can +contain the primary arguments or any others.} \item{object}{A logistic regression model specification.} \item{fresh}{A logical for whether the arguments should be modified in-place of or replaced wholesale.} } -\value{ -An updated model specification. -} \description{ \code{logistic_reg} is a way to generate a \emph{specification} of a model before fitting and allows the model to be created using @@ -53,7 +47,7 @@ the model. Note that this will be ignored for some engines. } These arguments are converted to their specific names at the time that the model is fit. Other options and argument can be -set using the \code{others} argument. If left to their defaults +set using the \code{...} slot. If left to their defaults here (\code{NULL}), the values are taken from the underlying model functions. If parameters need to be modified, \code{update} can be used in lieu of recreating the object from scratch. @@ -68,9 +62,26 @@ following \emph{engines}: \item \pkg{Stan}: \code{"stan"} \item \pkg{Spark}: \code{"spark"} } +} +\note{ +For models created using the spark engine, there are +several differences to consider. First, only the formula +interface to via \code{fit} is available; using \code{fit_xy} will +generate an error. Second, the predictions will always be in a +spark table format. The names will be the same as documented but +without the dots. Third, there is no equivalent to factor +columns in spark tables so class predictions are returned as +character columns. Fourth, to retain the model object for a new +R session (via \code{save}), the \code{model$fit} element of the \code{parsnip} +object should be serialized via \code{ml_save(object$fit)} and +separately saved to disk. In a new session, the object can be +reloaded and reattached to the \code{parsnip} object. +} +\section{Engine Details}{ + Engines may have pre-set default arguments when executing the -model fit call. These can be changed by using the \code{others} +model fit call. These can be changed by using the \code{...} argument to pass in the preferred values. For this type of model, the template of the fit calls are: @@ -108,20 +119,7 @@ distribution (or posterior predictive distribution as appropriate) is returned. For \code{glm}, the standard error is in logit units while the intervals are in probability units. } -\note{ -For models created using the spark engine, there are -several differences to consider. First, only the formula -interface to via \code{fit} is available; using \code{fit_xy} will -generate an error. Second, the predictions will always be in a -spark table format. The names will be the same as documented but -without the dots. Third, there is no equivalent to factor -columns in spark tables so class predictions are returned as -character columns. Fourth, to retain the model object for a new -R session (via \code{save}), the \code{model$fit} element of the \code{parsnip} -object should be serialized via \code{ml_save(object$fit)} and -separately saved to disk. In a new session, the object can be -reloaded and reattached to the \code{parsnip} object. -} + \examples{ logistic_reg() # Parameters can be represented by a placeholder: diff --git a/man/mars.Rd b/man/mars.Rd index f19dbc139..9f4d25e03 100644 --- a/man/mars.Rd +++ b/man/mars.Rd @@ -5,20 +5,17 @@ \alias{update.mars} \title{General Interface for MARS} \usage{ -mars(mode = "unknown", ..., num_terms = NULL, prod_degree = NULL, - prune_method = NULL, others = list()) +mars(mode = "unknown", num_terms = NULL, prod_degree = NULL, + prune_method = NULL, ...) \method{update}{mars}(object, num_terms = NULL, prod_degree = NULL, - prune_method = NULL, others = list(), fresh = FALSE, ...) + prune_method = NULL, fresh = FALSE, ...) } \arguments{ \item{mode}{A single character string for the type of model. Possible values for this model are "unknown", "regression", or "classification".} -\item{...}{Used for method consistency. Any arguments passed to -the ellipses will result in an error. Use \code{others} instead.} - \item{num_terms}{The number of features that will be retained in the final model, including the intercept.} @@ -26,20 +23,17 @@ final model, including the intercept.} \item{prune_method}{The pruning method.} -\item{others}{A named list of arguments to be used by the -underlying models (e.g., \code{earth::earth}, etc.). If the outcome is a factor -and \code{mode = "classification"}, \code{others} can include the \code{glm} argument to -\code{earth::earth}. If this argument is not passed, it will be added prior to -the fitting occurs.} +\item{...}{Other arguments to pass to the specific engine's +model fit function (see the Engine Details section below). This +should not include arguments defined by the main parameters to +this function. For the \code{update} function, the ellipses can +contain the primary arguments or any others.} \item{object}{A MARS model specification.} \item{fresh}{A logical for whether the arguments should be modified in-place of or replaced wholesale.} } -\value{ -An updated model specification. -} \description{ \code{mars} is a way to generate a \emph{specification} of a model before fitting and allows the model to be created using R. The main @@ -56,13 +50,13 @@ in \code{?earth}. } These arguments are converted to their specific names at the time that the model is fit. Other options and argument can be -set using the \code{others} argument. If left to their defaults +set using the \code{...} slot. If left to their defaults here (\code{NULL}), the values are taken from the underlying model functions. If parameters need to be modified, \code{update} can be used in lieu of recreating the object from scratch. } \details{ -Main parameter arguments (and those in \code{others}) can avoid +Main parameter arguments (and those in \code{...}) can avoid evaluation until the underlying function is executed by wrapping the argument in \code{\link[rlang:expr]{rlang::expr()}}. @@ -71,9 +65,12 @@ following \emph{engines}: \itemize{ \item \pkg{R}: \code{"earth"} } +} +\section{Engine Details}{ + Engines may have pre-set default arguments when executing the -model fit call. These can be changed by using the \code{others} +model fit call. These can be changed by using the \code{...} argument to pass in the preferred values. For this type of model, the template of the fit calls are: @@ -89,6 +86,7 @@ Note that, when the model is fit, the \pkg{earth} package only has its namespace loaded. However, if \code{multi_predict} is used, the package is attached. } + \examples{ mars(mode = "regression", num_terms = 5) model <- mars(num_terms = 10, prune_method = "none") diff --git a/man/mlp.Rd b/man/mlp.Rd index 437e93f79..807fd04ae 100644 --- a/man/mlp.Rd +++ b/man/mlp.Rd @@ -5,22 +5,18 @@ \alias{update.mlp} \title{General Interface for Single Layer Neural Network} \usage{ -mlp(mode = "unknown", ..., hidden_units = NULL, penalty = NULL, - dropout = NULL, epochs = NULL, activation = NULL, - others = list()) +mlp(mode = "unknown", hidden_units = NULL, penalty = NULL, + dropout = NULL, epochs = NULL, activation = NULL, ...) \method{update}{mlp}(object, hidden_units = NULL, penalty = NULL, - dropout = NULL, epochs = NULL, activation = NULL, - others = list(), fresh = FALSE, ...) + dropout = NULL, epochs = NULL, activation = NULL, fresh = FALSE, + ...) } \arguments{ \item{mode}{A single character string for the type of model. Possible values for this model are "unknown", "regression", or "classification".} -\item{...}{Used for method consistency. Any arguments passed to -the ellipses will result in an error. Use \code{others} instead.} - \item{hidden_units}{An integer for the number of units in the hidden model.} \item{penalty}{A non-negative numeric value for the amount of weight @@ -37,18 +33,17 @@ function between the hidden and output layers is automatically set to either "linear" or "softmax" depending on the type of outcome. Possible values are: "linear", "softmax", "relu", and "elu"} -\item{others}{A named list of arguments to be used by the -underlying models (e.g., \code{nnet::nnet}, -\code{keras::fit}, \code{keras::compile}, etc.). .} +\item{...}{Other arguments to pass to the specific engine's +model fit function (see the Engine Details section below). This +should not include arguments defined by the main parameters to +this function. For the \code{update} function, the ellipses can +contain the primary arguments or any others.} \item{object}{A random forest model specification.} \item{fresh}{A logical for whether the arguments should be modified in-place of or replaced wholesale.} } -\value{ -An updated model specification. -} \description{ \code{mlp}, for multilayer perceptron, is a way to generate a \emph{specification} of a model before fitting and allows the model to be created using @@ -72,7 +67,7 @@ in lieu of recreating the object from scratch. \details{ These arguments are converted to their specific names at the time that the model is fit. Other options and argument can be -set using the \code{others} argument. If left to their defaults +set using the \code{...} slot. If left to their defaults here (see above), the values are taken from the underlying model functions. One exception is \code{hidden_units} when \code{nnet::nnet} is used; that function's \code{size} argument has no default so a value of 5 units will be @@ -88,15 +83,18 @@ following \emph{engines}: \item \pkg{keras}: \code{"keras"} } -Main parameter arguments (and those in \code{others}) can avoid +Main parameter arguments (and those in \code{...}) can avoid evaluation until the underlying function is executed by wrapping the argument in \code{\link[rlang:expr]{rlang::expr()}} (e.g. \code{hidden_units = expr(num_preds * 2)}). An error is thrown if both \code{penalty} and \code{dropout} are specified for \code{keras} models. +} +\section{Engine Details}{ + Engines may have pre-set default arguments when executing the -model fit call. These can be changed by using the \code{others} +model fit call. These can be changed by using the \code{...} argument to pass in the preferred values. For this type of model, the template of the fit calls are: @@ -116,6 +114,7 @@ model, the template of the fit calls are: \Sexpr[results=rd]{parsnip:::show_fit(parsnip:::mlp(mode = "regression"), "nnet")} } + \examples{ mlp(mode = "classification", penalty = 0.01) # Parameters can be represented by a placeholder: diff --git a/man/multinom_reg.Rd b/man/multinom_reg.Rd index 91a650952..db9ba3614 100644 --- a/man/multinom_reg.Rd +++ b/man/multinom_reg.Rd @@ -5,19 +5,16 @@ \alias{update.multinom_reg} \title{General Interface for Multinomial Regression Models} \usage{ -multinom_reg(mode = "classification", ..., penalty = NULL, - mixture = NULL, others = list()) +multinom_reg(mode = "classification", penalty = NULL, mixture = NULL, + ...) \method{update}{multinom_reg}(object, penalty = NULL, mixture = NULL, - others = list(), fresh = FALSE, ...) + fresh = FALSE, ...) } \arguments{ \item{mode}{A single character string for the type of model. The only possible value for this model is "classification".} -\item{...}{Used for S3 method consistency. Any arguments passed to -the ellipses will result in an error. Use \code{others} instead.} - \item{penalty}{An non-negative number representing the total amount of regularization.} @@ -26,19 +23,17 @@ represents the proportion of regularization that is used for the L2 penalty (i.e. weight decay, or ridge regression) versus L1 (the lasso) (\code{glmnet} only).} -\item{others}{A named list of arguments to be used by the -underlying models (e.g., \code{glmnet::glmnet} etc.). These are not evaluated -until the model is fit and will be substituted into the model -fit expression.} +\item{...}{Other arguments to pass to the specific engine's +model fit function (see the Engine Details section below). This +should not include arguments defined by the main parameters to +this function. For the \code{update} function, the ellipses can +contain the primary arguments or any others.} \item{object}{A multinomial regression model specification.} \item{fresh}{A logical for whether the arguments should be modified in-place of or replaced wholesale.} } -\value{ -An updated model specification. -} \description{ \code{multinom_reg} is a way to generate a \emph{specification} of a model before fitting and allows the model to be created using @@ -52,7 +47,7 @@ the model. Note that this will be ignored for some engines. } These arguments are converted to their specific names at the time that the model is fit. Other options and argument can be -set using the \code{others} argument. If left to their defaults +set using the \code{...} slot. If left to their defaults here (\code{NULL}), the values are taken from the underlying model functions. If parameters need to be modified, \code{update} can be used in lieu of recreating the object from scratch. @@ -66,9 +61,26 @@ following \emph{engines}: \item \pkg{R}: \code{"glmnet"} \item \pkg{Stan}: \code{"stan"} } +} +\note{ +For models created using the spark engine, there are +several differences to consider. First, only the formula +interface to via \code{fit} is available; using \code{fit_xy} will +generate an error. Second, the predictions will always be in a +spark table format. The names will be the same as documented but +without the dots. Third, there is no equivalent to factor +columns in spark tables so class predictions are returned as +character columns. Fourth, to retain the model object for a new +R session (via \code{save}), the \code{model$fit} element of the \code{parsnip} +object should be serialized via \code{ml_save(object$fit)} and +separately saved to disk. In a new session, the object can be +reloaded and reattached to the \code{parsnip} object. +} +\section{Engine Details}{ + Engines may have pre-set default arguments when executing the -model fit call. These can be changed by using the \code{others} +model fit call. These can be changed by using the \code{...} argument to pass in the preferred values. For this type of model, the template of the fit calls are: @@ -90,20 +102,7 @@ multiple values or no values for \code{penalty} are used in \code{multinom_reg}, the \code{predict} method will return a data frame with columns \code{values} and \code{lambda}. } -\note{ -For models created using the spark engine, there are -several differences to consider. First, only the formula -interface to via \code{fit} is available; using \code{fit_xy} will -generate an error. Second, the predictions will always be in a -spark table format. The names will be the same as documented but -without the dots. Third, there is no equivalent to factor -columns in spark tables so class predictions are returned as -character columns. Fourth, to retain the model object for a new -R session (via \code{save}), the \code{model$fit} element of the \code{parsnip} -object should be serialized via \code{ml_save(object$fit)} and -separately saved to disk. In a new session, the object can be -reloaded and reattached to the \code{parsnip} object. -} + \examples{ multinom_reg() # Parameters can be represented by a placeholder: diff --git a/man/nearest_neighbor.Rd b/man/nearest_neighbor.Rd index 33bf3d34c..5851088c9 100644 --- a/man/nearest_neighbor.Rd +++ b/man/nearest_neighbor.Rd @@ -4,17 +4,14 @@ \alias{nearest_neighbor} \title{General Interface for K-Nearest Neighbor Models} \usage{ -nearest_neighbor(mode = "unknown", ..., neighbors = NULL, - weight_func = NULL, dist_power = NULL, others = list()) +nearest_neighbor(mode = "unknown", neighbors = NULL, + weight_func = NULL, dist_power = NULL, ...) } \arguments{ \item{mode}{A single character string for the type of model. Possible values for this model are \code{"unknown"}, \code{"regression"}, or \code{"classification"}.} -\item{...}{Used for S3 method consistency. Any arguments passed to -the ellipses will result in an error. Use \code{others} instead.} - \item{neighbors}{A single integer for the number of neighbors to consider (often called \code{k}).} @@ -26,10 +23,11 @@ to weight distances between samples. Valid choices are: \code{"rectangular"}, \item{dist_power}{A single number for the parameter used in calculating Minkowski distance.} -\item{others}{A named list of arguments to be used by the -underlying models (e.g., \code{kknn::train.kknn}). These are not evaluated -until the model is fit and will be substituted into the model -fit expression.} +\item{...}{Other arguments to pass to the specific engine's +model fit function (see the Engine Details section below). This +should not include arguments defined by the main parameters to +this function. For the \code{update} function, the ellipses can +contain the primary arguments or any others.} } \description{ \code{nearest_neighbor()} is a way to generate a \emph{specification} of a model @@ -47,7 +45,7 @@ and the Euclidean distance with \code{dist_power = 2}. } These arguments are converted to their specific names at the time that the model is fit. Other options and argument can be -set using the \code{others} argument. If left to their defaults +set using the \code{...} slot. If left to their defaults here (\code{NULL}), the values are taken from the underlying model functions. If parameters need to be modified, \code{update()} can be used in lieu of recreating the object from scratch. @@ -58,9 +56,19 @@ following \emph{engines}: \itemize{ \item \pkg{R}: \code{"kknn"} } +} +\note{ +For \code{kknn}, the underlying modeling function used is a restricted +version of \code{train.kknn()} and not \code{kknn()}. It is set up in this way so that +\code{parsnip} can utilize the underlying \code{predict.train.kknn} method to predict +on new data. This also means that a single value of that function's +\code{kernel} argument (a.k.a \code{weight_func} here) can be supplied +} +\section{Engine Details}{ + Engines may have pre-set default arguments when executing the -model fit call. These can be changed by using the \code{others} +model fit call. These can be changed by using the \code{...} argument to pass in the preferred values. For this type of model, the template of the fit calls are: @@ -68,13 +76,7 @@ model, the template of the fit calls are: \Sexpr[results=rd]{parsnip:::show_fit(parsnip:::nearest_neighbor(), "kknn")} } -\note{ -For \code{kknn}, the underlying modeling function used is a restricted -version of \code{train.kknn()} and not \code{kknn()}. It is set up in this way so that -\code{parsnip} can utilize the underlying \code{predict.train.kknn} method to predict -on new data. This also means that a single value of that function's -\code{kernel} argument (a.k.a \code{weight_func} here) can be supplied -} + \examples{ nearest_neighbor() diff --git a/man/rand_forest.Rd b/man/rand_forest.Rd index a7f23e074..7f5e2e604 100644 --- a/man/rand_forest.Rd +++ b/man/rand_forest.Rd @@ -5,20 +5,17 @@ \alias{update.rand_forest} \title{General Interface for Random Forest Models} \usage{ -rand_forest(mode = "unknown", ..., mtry = NULL, trees = NULL, - min_n = NULL, others = list()) +rand_forest(mode = "unknown", mtry = NULL, trees = NULL, + min_n = NULL, ...) \method{update}{rand_forest}(object, mtry = NULL, trees = NULL, - min_n = NULL, others = list(), fresh = FALSE, ...) + min_n = NULL, fresh = FALSE, ...) } \arguments{ \item{mode}{A single character string for the type of model. Possible values for this model are "unknown", "regression", or "classification".} -\item{...}{Used for method consistency. Any arguments passed to -the ellipses will result in an error. Use \code{others} instead.} - \item{mtry}{An integer for the number of predictors that will be randomly sampled at each split when creating the tree models.} @@ -28,18 +25,17 @@ the ensemble.} \item{min_n}{An integer for the minimum number of data points in a node that are required for the node to be split further.} -\item{others}{A named list of arguments to be used by the -underlying models (e.g., \code{ranger::ranger}, -\code{randomForest::randomForest}, etc.). .} +\item{...}{Other arguments to pass to the specific engine's +model fit function (see the Engine Details section below). This +should not include arguments defined by the main parameters to +this function. For the \code{update} function, the ellipses can +contain the primary arguments or any others.} \item{object}{A random forest model specification.} \item{fresh}{A logical for whether the arguments should be modified in-place of or replaced wholesale.} } -\value{ -An updated model specification. -} \description{ \code{rand_forest} is a way to generate a \emph{specification} of a model before fitting and allows the model to be created using @@ -54,7 +50,7 @@ that are required for the node to be split further. } These arguments are converted to their specific names at the time that the model is fit. Other options and argument can be -set using the \code{others} argument. If left to their defaults +set using the \code{...} slot. If left to their defaults here (\code{NULL}), the values are taken from the underlying model functions. If parameters need to be modified, \code{update} can be used in lieu of recreating the object from scratch. @@ -67,14 +63,31 @@ following \emph{engines}: \item \pkg{Spark}: \code{"spark"} } -Main parameter arguments (and those in \code{others}) can avoid +Main parameter arguments (and those in \code{...}) can avoid evaluation until the underlying function is executed by wrapping the argument in \code{\link[rlang:expr]{rlang::expr()}} (e.g. \code{mtry = expr(floor(sqrt(p)))}). +} +\note{ +For models created using the spark engine, there are +several differences to consider. First, only the formula +interface to via \code{fit} is available; using \code{fit_xy} will +generate an error. Second, the predictions will always be in a +spark table format. The names will be the same as documented but +without the dots. Third, there is no equivalent to factor +columns in spark tables so class predictions are returned as +character columns. Fourth, to retain the model object for a new +R session (via \code{save}), the \code{model$fit} element of the \code{parsnip} +object should be serialized via \code{ml_save(object$fit)} and +separately saved to disk. In a new session, the object can be +reloaded and reattached to the \code{parsnip} object. +} +\section{Engine Details}{ + Engines may have pre-set default arguments when executing the -model fit call. These can be changed by using the \code{others} +model fit call. These can be changed by using the \code{...} argument to pass in the preferred values. For this type of -model, the template of the fit calls are: +model, the template of the fit calls are:: \pkg{ranger} classification @@ -105,20 +118,7 @@ constructed using the form \code{estimate +/- z * std_error}. For classification probabilities, these values can fall outside of \code{[0, 1]} and will be coerced to be in this range. } -\note{ -For models created using the spark engine, there are -several differences to consider. First, only the formula -interface to via \code{fit} is available; using \code{fit_xy} will -generate an error. Second, the predictions will always be in a -spark table format. The names will be the same as documented but -without the dots. Third, there is no equivalent to factor -columns in spark tables so class predictions are returned as -character columns. Fourth, to retain the model object for a new -R session (via \code{save}), the \code{model$fit} element of the \code{parsnip} -object should be serialized via \code{ml_save(object$fit)} and -separately saved to disk. In a new session, the object can be -reloaded and reattached to the \code{parsnip} object. -} + \examples{ rand_forest(mode = "classification", trees = 2000) # Parameters can be represented by a placeholder: diff --git a/man/surv_reg.Rd b/man/surv_reg.Rd index a9ee647a6..cca86a6e2 100644 --- a/man/surv_reg.Rd +++ b/man/surv_reg.Rd @@ -5,34 +5,28 @@ \alias{update.surv_reg} \title{General Interface for Parametric Survival Models} \usage{ -surv_reg(mode = "regression", ..., dist = NULL, others = list()) +surv_reg(mode = "regression", dist = NULL, ...) -\method{update}{surv_reg}(object, dist = NULL, others = list(), - fresh = FALSE, ...) +\method{update}{surv_reg}(object, dist = NULL, fresh = FALSE, ...) } \arguments{ \item{mode}{A single character string for the type of model. The only possible value for this model is "regression".} -\item{...}{Used for S3 method consistency. Any arguments passed to -the ellipses will result in an error. Use \code{others} instead.} - \item{dist}{A character string for the outcome distribution. "weibull" is the default.} -\item{others}{A named list of arguments to be used by the -underlying models (e.g., \code{flexsurv::flexsurvreg}). These are not evaluated -until the model is fit and will be substituted into the model -fit expression.} +\item{...}{Other arguments to pass to the specific engine's +model fit function (see the Engine Details section below). This +should not include arguments defined by the main parameters to +this function. For the \code{update} function, the ellipses can +contain the primary arguments or any others.} \item{object}{A survival regression model specification.} \item{fresh}{A logical for whether the arguments should be modified in-place of or replaced wholesale.} } -\value{ -An updated model specification. -} \description{ \code{surv_reg} is a way to generate a \emph{specification} of a model before fitting and allows the model to be created using @@ -43,7 +37,7 @@ model is: } This argument is converted to its specific names at the time that the model is fit. Other options and argument can be -set using the \code{others} argument. If left to its default +set using the \code{...} slot. If left to its default here (\code{NULL}), the value is taken from the underlying model functions. diff --git a/tests/testthat/test_args_and_modes.R b/tests/testthat/test_args_and_modes.R index 317663501..a7587a6c2 100644 --- a/tests/testthat/test_args_and_modes.R +++ b/tests/testthat/test_args_and_modes.R @@ -1,23 +1,56 @@ library(testthat) library(parsnip) library(dplyr) +library(rlang) context("changing arguments and engine") test_that('pipe arguments', { mod_1 <- rand_forest() %>% set_args(mtry = 1, something = "blah") - expect_equal(mod_1$args$mtry, 1) - expect_equal(mod_1$others$something, "blah") - - mod_2 <- rand_forest(mtry = 2, others = list(var = "x")) %>% + expect_equal( + quo_get_expr(mod_1$args$mtry), + 1 + ) + expect_equal( + quo_get_env(mod_1$args$mtry), + empty_env() + ) + expect_equal( + quo_get_expr(mod_1$others$something), + "blah" + ) + expect_equal( + quo_get_env(mod_1$others$something), + empty_env() + ) + + x <- 1:10 + mod_2 <- rand_forest(mtry = 2, var = x) %>% set_args(mtry = 1, something = "blah") - expect_equal(mod_2$args$mtry, 1) - expect_equal(mod_2$others$something, "blah") - expect_equal(mod_2$others$var, "x") - + expect_equal( + quo_get_expr(mod_2$args$mtry), + 1 + ) + expect_equal( + quo_get_env(mod_2$args$mtry), + empty_env() + ) + expect_equal( + quo_get_expr(mod_2$others$something), + "blah" + ) + expect_equal( + quo_get_env(mod_2$others$something), + empty_env() + ) + expect_equal( + quo_get_env(mod_2$others$var), + global_env() + ) + expect_error(rand_forest() %>% set_args()) - + }) @@ -25,8 +58,8 @@ test_that('pipe engine', { mod_1 <- rand_forest() %>% set_mode("regression") expect_equal(mod_1$mode, "regression") - + expect_error(rand_forest() %>% set_mode()) expect_error(rand_forest() %>% set_mode(2)) expect_error(rand_forest() %>% set_mode("haberdashery")) -}) \ No newline at end of file +})