From 101a61c612d7cf19f4bdd055bd47a973600c5cb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=98topepo=E2=80=99?= Date: Sun, 30 Nov 2025 17:08:15 -0500 Subject: [PATCH 1/8] doc updates --- man/details_bart_dbarts.Rd | 7 ++++-- man/details_boost_tree_h2o.Rd | 6 +++-- man/details_boost_tree_xgboost.Rd | 5 +++- man/details_decision_tree_partykit.Rd | 16 ++++++------- man/details_proportional_hazards_glmnet.Rd | 17 ++++++++++++++ man/details_rand_forest_aorsf.Rd | 24 +++++++++---------- man/details_rand_forest_partykit.Rd | 16 ++++++------- man/details_svm_rbf_kernlab.Rd | 24 +++++++++++-------- man/rmd/decision_tree_partykit.md | 16 ++++++------- man/rmd/rand_forest_aorsf.Rmd | 3 ++- man/rmd/rand_forest_aorsf.md | 27 +++++++++++----------- man/rmd/rand_forest_partykit.md | 16 ++++++------- vignettes/parsnip.Rmd | 2 +- 13 files changed, 105 insertions(+), 74 deletions(-) diff --git a/man/details_bart_dbarts.Rd b/man/details_bart_dbarts.Rd index 352bc0467..49a2c5685 100644 --- a/man/details_bart_dbarts.Rd +++ b/man/details_bart_dbarts.Rd @@ -124,7 +124,8 @@ indicators if the user does not create them first. \subsection{Prediction types}{ \if{html}{\out{
}}\preformatted{parsnip:::get_from_env("bart_predict") |> - dplyr::select(mode, type) + dplyr::select(mode, type) |> + print(n = Inf) }\if{html}{\out{
}} \if{html}{\out{
}}\preformatted{## # A tibble: 9 x 2 @@ -136,7 +137,9 @@ indicators if the user does not create them first. ## 4 regression pred_int ## 5 classification class ## 6 classification prob -## # i 3 more rows +## 7 classification conf_int +## 8 classification pred_int +## 9 classification raw }\if{html}{\out{
}} } diff --git a/man/details_boost_tree_h2o.Rd b/man/details_boost_tree_h2o.Rd index 94ad47e74..801067b33 100644 --- a/man/details_boost_tree_h2o.Rd +++ b/man/details_boost_tree_h2o.Rd @@ -160,7 +160,8 @@ within \verb{[0, 1]}. \if{html}{\out{
}}\preformatted{parsnip:::get_from_env("boost_tree_predict") |> dplyr::filter(stringr::str_starts(engine, "h2o")) |> - dplyr::select(mode, type) + dplyr::select(mode, type) |> + print(n = Inf) }\if{html}{\out{
}} \if{html}{\out{
}}\preformatted{## # A tibble: 8 x 2 @@ -172,7 +173,8 @@ within \verb{[0, 1]}. ## 4 classification prob ## 5 regression numeric ## 6 regression raw -## # i 2 more rows +## 7 classification class +## 8 classification prob }\if{html}{\out{
}} } diff --git a/man/details_boost_tree_xgboost.Rd b/man/details_boost_tree_xgboost.Rd index dca1b8843..f68aa83f4 100644 --- a/man/details_boost_tree_xgboost.Rd +++ b/man/details_boost_tree_xgboost.Rd @@ -9,7 +9,10 @@ ensemble. Each tree depends on the results of previous trees. All trees in the ensemble are combined to produce a final prediction. } \details{ -For this engine, there are multiple modes: classification and regression +For this engine, there are multiple modes: classification and +regression. Note that in late 2025, a new version of xgboost was +released with differences in its interface and model objects. This +version of parsnip should work with either version. \subsection{Tuning Parameters}{ This model has 8 tuning parameters: diff --git a/man/details_decision_tree_partykit.Rd b/man/details_decision_tree_partykit.Rd index 0d0ef6027..279df8fec 100644 --- a/man/details_decision_tree_partykit.Rd +++ b/man/details_decision_tree_partykit.Rd @@ -8,14 +8,14 @@ tree-based structure using hypothesis testing methods. } \details{ -For this engine, there are multiple modes: censored regression, -regression, and classification +For this engine, there are multiple modes: regression, classification, +and censored regression \subsection{Tuning Parameters}{ This model has 2 tuning parameters: \itemize{ -\item \code{tree_depth}: Tree Depth (type: integer, default: see below) \item \code{min_n}: Minimal Node Size (type: integer, default: 20L) +\item \code{tree_depth}: Tree Depth (type: integer, default: see below) } The \code{tree_depth} parameter defaults to \code{0} which means no restrictions @@ -135,11 +135,11 @@ are not required for this model. \if{html}{\out{
}}\preformatted{## # A tibble: 5 x 2 ## mode type ## -## 1 censored regression time -## 2 censored regression survival -## 3 regression numeric -## 4 classification class -## 5 classification prob +## 1 regression numeric +## 2 classification class +## 3 classification prob +## 4 censored regression time +## 5 censored regression survival }\if{html}{\out{
}} } diff --git a/man/details_proportional_hazards_glmnet.Rd b/man/details_proportional_hazards_glmnet.Rd index 3322a7c0c..7dcd2ff1a 100644 --- a/man/details_proportional_hazards_glmnet.Rd +++ b/man/details_proportional_hazards_glmnet.Rd @@ -154,6 +154,23 @@ predictions. When saving the model for the purpose of prediction, the size of the saved object might be substantially reduced by using functions from the \href{https://butcher.tidymodels.org}{butcher} package. } + +\subsection{Prediction types}{ + +\if{html}{\out{
}}\preformatted{parsnip:::get_from_env("proportional_hazards_predict") |> + dplyr::filter(engine == "glmnet") |> + dplyr::select(mode, type) +}\if{html}{\out{
}} + +\if{html}{\out{
}}\preformatted{## # A tibble: 4 x 2 +## mode type +## +## 1 censored regression linear_pred +## 2 censored regression survival +## 3 censored regression time +## 4 censored regression raw +}\if{html}{\out{
}} +} } \section{References}{ \itemize{ diff --git a/man/details_rand_forest_aorsf.Rd b/man/details_rand_forest_aorsf.Rd index 6ccb4d7d6..c263f25ad 100644 --- a/man/details_rand_forest_aorsf.Rd +++ b/man/details_rand_forest_aorsf.Rd @@ -9,16 +9,16 @@ trees, each de-correlated from the others. The final prediction uses all predictions from the individual trees and combines them. } \details{ -For this engine, there are multiple modes: censored regression, -classification, and regression +For this engine, there are multiple modes: classification, regression, +and censored regression \subsection{Tuning Parameters}{ This model has 3 tuning parameters: \itemize{ -\item \code{trees}: # Trees (type: integer, default: 500L) -\item \code{min_n}: Minimal Node Size (type: integer, default: 5L) \item \code{mtry}: # Randomly Selected Predictors (type: integer, default: ceiling(sqrt(n_predictors))) +\item \code{trees}: # Trees (type: integer, default: 500L) +\item \code{min_n}: Minimal Node Size (type: integer, default: 5L) } Additionally, this model has one engine-specific tuning parameter: @@ -123,14 +123,14 @@ The \code{fit()} and \code{fit_xy()} arguments have arguments called }\if{html}{\out{}} \if{html}{\out{
}}\preformatted{## # A tibble: 7 x 2 -## mode type -## -## 1 censored regression time -## 2 censored regression survival -## 3 classification class -## 4 classification prob -## 5 classification raw -## 6 regression numeric +## mode type +## +## 1 classification class +## 2 classification prob +## 3 classification raw +## 4 regression numeric +## 5 regression raw +## 6 censored regression time ## # i 1 more row }\if{html}{\out{
}} } diff --git a/man/details_rand_forest_partykit.Rd b/man/details_rand_forest_partykit.Rd index 4af378e97..a6f392a53 100644 --- a/man/details_rand_forest_partykit.Rd +++ b/man/details_rand_forest_partykit.Rd @@ -9,15 +9,15 @@ trees, each independent of the others. The final prediction uses all predictions from the individual trees and combines them. } \details{ -For this engine, there are multiple modes: censored regression, -regression, and classification +For this engine, there are multiple modes: regression, classification, +and censored regression \subsection{Tuning Parameters}{ This model has 3 tuning parameters: \itemize{ -\item \code{trees}: # Trees (type: integer, default: 500L) \item \code{min_n}: Minimal Node Size (type: integer, default: 20L) \item \code{mtry}: # Randomly Selected Predictors (type: integer, default: 5L) +\item \code{trees}: # Trees (type: integer, default: 500L) } } @@ -110,11 +110,11 @@ are not required for this model. \if{html}{\out{
}}\preformatted{## # A tibble: 5 x 2 ## mode type ## -## 1 censored regression time -## 2 censored regression survival -## 3 regression numeric -## 4 classification class -## 5 classification prob +## 1 regression numeric +## 2 classification class +## 3 classification prob +## 4 censored regression time +## 5 censored regression survival }\if{html}{\out{
}} } diff --git a/man/details_svm_rbf_kernlab.Rd b/man/details_svm_rbf_kernlab.Rd index 897538684..5b9946557 100644 --- a/man/details_svm_rbf_kernlab.Rd +++ b/man/details_svm_rbf_kernlab.Rd @@ -111,19 +111,23 @@ The underlying model implementation does not allow for case weights. \subsection{Prediction types}{ \if{html}{\out{
}}\preformatted{parsnip:::get_from_env("svm_rbf_predict") |> - dplyr::select(mode, type) + dplyr::select(mode, type) |> + print(n = Inf) }\if{html}{\out{
}} \if{html}{\out{
}}\preformatted{## # A tibble: 10 x 2 -## mode type -## -## 1 regression numeric -## 2 regression raw -## 3 classification class -## 4 classification prob -## 5 classification raw -## 6 regression numeric -## # i 4 more rows +## mode type +## +## 1 regression numeric +## 2 regression raw +## 3 classification class +## 4 classification prob +## 5 classification raw +## 6 regression numeric +## 7 regression raw +## 8 classification class +## 9 classification prob +## 10 classification raw }\if{html}{\out{
}} } diff --git a/man/rmd/decision_tree_partykit.md b/man/rmd/decision_tree_partykit.md index 9d712e4e2..2cce9c12d 100644 --- a/man/rmd/decision_tree_partykit.md +++ b/man/rmd/decision_tree_partykit.md @@ -1,7 +1,7 @@ -For this engine, there are multiple modes: regression, classification, and censored regression +For this engine, there are multiple modes: censored regression, regression, and classification ## Tuning Parameters @@ -9,10 +9,10 @@ For this engine, there are multiple modes: regression, classification, and censo This model has 2 tuning parameters: -- `min_n`: Minimal Node Size (type: integer, default: 20L) - - `tree_depth`: Tree Depth (type: integer, default: see below) +- `min_n`: Minimal Node Size (type: integer, default: 20L) + The `tree_depth` parameter defaults to `0` which means no restrictions are applied to tree depth. An engine-specific parameter for this model is: @@ -128,11 +128,11 @@ parsnip:::get_from_env("decision_tree_predict") |> ## # A tibble: 5 x 2 ## mode type ## -## 1 regression numeric -## 2 classification class -## 3 classification prob -## 4 censored regression time -## 5 censored regression survival +## 1 censored regression time +## 2 censored regression survival +## 3 regression numeric +## 4 classification class +## 5 classification prob ``` ## Other details diff --git a/man/rmd/rand_forest_aorsf.Rmd b/man/rmd/rand_forest_aorsf.Rmd index 349a31f68..42f5a0276 100644 --- a/man/rmd/rand_forest_aorsf.Rmd +++ b/man/rmd/rand_forest_aorsf.Rmd @@ -96,7 +96,8 @@ rand_forest() |> parsnip:::get_from_env("rand_forest_predict") |> dplyr::filter(engine == "aorsf") |> - dplyr::select(mode, type) + dplyr::select(mode, type)|> + print(n = Inf) ``` diff --git a/man/rmd/rand_forest_aorsf.md b/man/rmd/rand_forest_aorsf.md index 2c8a53b4f..7773a2d55 100644 --- a/man/rmd/rand_forest_aorsf.md +++ b/man/rmd/rand_forest_aorsf.md @@ -1,7 +1,7 @@ -For this engine, there are multiple modes: classification, regression, and censored regression +For this engine, there are multiple modes: censored regression, classification, and regression ## Tuning Parameters @@ -9,12 +9,12 @@ For this engine, there are multiple modes: classification, regression, and censo This model has 3 tuning parameters: -- `mtry`: # Randomly Selected Predictors (type: integer, default: ceiling(sqrt(n_predictors))) - - `trees`: # Trees (type: integer, default: 500L) - `min_n`: Minimal Node Size (type: integer, default: 5L) +- `mtry`: # Randomly Selected Predictors (type: integer, default: ceiling(sqrt(n_predictors))) + Additionally, this model has one engine-specific tuning parameter: * `split_min_stat`: Minimum test statistic required to split a node. Defaults are `3.841459` for censored regression (which is roughly a p-value of 0.05) and `0` for classification and regression. For classification, this tuning parameter should be between 0 and 1, and for regression it should be greater than or equal to 0. Higher values of this parameter cause trees grown by `aorsf` to have less depth. @@ -108,20 +108,21 @@ The `fit()` and `fit_xy()` arguments have arguments called `case_weights` that e ``` r parsnip:::get_from_env("rand_forest_predict") |> dplyr::filter(engine == "aorsf") |> - dplyr::select(mode, type) + dplyr::select(mode, type)|> + print(n = Inf) ``` ``` ## # A tibble: 7 x 2 -## mode type -## -## 1 classification class -## 2 classification prob -## 3 classification raw -## 4 regression numeric -## 5 regression raw -## 6 censored regression time -## # i 1 more row +## mode type +## +## 1 censored regression time +## 2 censored regression survival +## 3 classification class +## 4 classification prob +## 5 classification raw +## 6 regression numeric +## 7 regression raw ``` ## Other details diff --git a/man/rmd/rand_forest_partykit.md b/man/rmd/rand_forest_partykit.md index a5e76e1b8..35b9db9be 100644 --- a/man/rmd/rand_forest_partykit.md +++ b/man/rmd/rand_forest_partykit.md @@ -1,7 +1,7 @@ -For this engine, there are multiple modes: regression, classification, and censored regression +For this engine, there are multiple modes: censored regression, regression, and classification ## Tuning Parameters @@ -9,12 +9,12 @@ For this engine, there are multiple modes: regression, classification, and censo This model has 3 tuning parameters: +- `trees`: # Trees (type: integer, default: 500L) + - `min_n`: Minimal Node Size (type: integer, default: 20L) - `mtry`: # Randomly Selected Predictors (type: integer, default: 5L) -- `trees`: # Trees (type: integer, default: 500L) - ## Translation from parsnip to the original package (regression) The **bonsai** extension package is required to fit this model. @@ -110,11 +110,11 @@ parsnip:::get_from_env("rand_forest_predict") |> ## # A tibble: 5 x 2 ## mode type ## -## 1 regression numeric -## 2 classification class -## 3 classification prob -## 4 censored regression time -## 5 censored regression survival +## 1 censored regression time +## 2 censored regression survival +## 3 regression numeric +## 4 classification class +## 5 classification prob ``` ## Other details diff --git a/vignettes/parsnip.Rmd b/vignettes/parsnip.Rmd index a2474bceb..3718eec1a 100644 --- a/vignettes/parsnip.Rmd +++ b/vignettes/parsnip.Rmd @@ -159,7 +159,7 @@ rf_with_seed |> Note that the call objects show `num.trees = ~2000`. The tilde is the consequence of `parsnip` using [quosures](https://adv-r.hadley.nz/evaluation.html#quosures) to process the model specification's arguments. -Normally, when a function is executed, the function's arguments are immediately evaluated. In the case of parsnip, the model specification's arguments are _not_; the [expression is captured](https://www.tidyverse.org/blog/2019/04/parsnip-internals/) along with the environment where it should be evaluated. That is what a quosure does. +Normally, when a function is executed, the function's arguments are immediately evaluated. In the case of parsnip, the model specification's arguments are _not_; the [expression is captured](https://tidyverse.org/blog/2019/04/parsnip-internals/) along with the environment where it should be evaluated. That is what a quosure does. parsnip uses these expressions to make a model fit call that is evaluated. The tilde in the call above reflects that the argument was captured using a quosure. From 1f1835b0941a896ed177e3a6f44d3c435fb9516a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=98topepo=E2=80=99?= Date: Sun, 30 Nov 2025 17:09:19 -0500 Subject: [PATCH 2/8] verison bumps --- DESCRIPTION | 2 +- NEWS.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 74f62fa96..44d20ca1a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: parsnip Title: A Common API to Modeling and Analysis Functions -Version: 1.3.3.9001 +Version: 1.4.0 Authors@R: c( person("Max", "Kuhn", , "max@posit.co", role = c("aut", "cre")), person("Davis", "Vaughan", , "davis@posit.co", role = "aut"), diff --git a/NEWS.md b/NEWS.md index d52d6950b..b88d5eee0 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# parsnip (development version) +# parsnip 1.4.0 * Fixes issue with running predictions for Decision Trees in Spark (#1309) From f6f124039769e2e82a0807993e26d319ac176ff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=98topepo=E2=80=99?= Date: Sun, 30 Nov 2025 17:09:43 -0500 Subject: [PATCH 3/8] updated tsv --- inst/models.tsv | 2 ++ 1 file changed, 2 insertions(+) diff --git a/inst/models.tsv b/inst/models.tsv index 2c39fff0c..a1ab034e7 100644 --- a/inst/models.tsv +++ b/inst/models.tsv @@ -14,11 +14,13 @@ "bart" "regression" "dbarts" NA "boost_tree" "censored regression" "mboost" "censored" "boost_tree" "classification" "C5.0" NA +"boost_tree" "classification" "catboost" "bonsai" "boost_tree" "classification" "h2o" "agua" "boost_tree" "classification" "h2o_gbm" "agua" "boost_tree" "classification" "lightgbm" "bonsai" "boost_tree" "classification" "spark" NA "boost_tree" "classification" "xgboost" NA +"boost_tree" "regression" "catboost" "bonsai" "boost_tree" "regression" "h2o" "agua" "boost_tree" "regression" "h2o_gbm" "agua" "boost_tree" "regression" "lightgbm" "bonsai" From b34bdeab64a21e56b6911f2eeb7f1e9e841fdecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=98topepo=E2=80=99?= Date: Sun, 30 Nov 2025 17:15:43 -0500 Subject: [PATCH 4/8] more doc updates --- man/details_decision_tree_partykit.Rd | 16 +++++++-------- man/details_rand_forest_aorsf.Rd | 29 ++++++++++++++------------- man/details_rand_forest_partykit.Rd | 16 +++++++-------- 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/man/details_decision_tree_partykit.Rd b/man/details_decision_tree_partykit.Rd index 279df8fec..0d0ef6027 100644 --- a/man/details_decision_tree_partykit.Rd +++ b/man/details_decision_tree_partykit.Rd @@ -8,14 +8,14 @@ tree-based structure using hypothesis testing methods. } \details{ -For this engine, there are multiple modes: regression, classification, -and censored regression +For this engine, there are multiple modes: censored regression, +regression, and classification \subsection{Tuning Parameters}{ This model has 2 tuning parameters: \itemize{ -\item \code{min_n}: Minimal Node Size (type: integer, default: 20L) \item \code{tree_depth}: Tree Depth (type: integer, default: see below) +\item \code{min_n}: Minimal Node Size (type: integer, default: 20L) } The \code{tree_depth} parameter defaults to \code{0} which means no restrictions @@ -135,11 +135,11 @@ are not required for this model. \if{html}{\out{
}}\preformatted{## # A tibble: 5 x 2 ## mode type ## -## 1 regression numeric -## 2 classification class -## 3 classification prob -## 4 censored regression time -## 5 censored regression survival +## 1 censored regression time +## 2 censored regression survival +## 3 regression numeric +## 4 classification class +## 5 classification prob }\if{html}{\out{
}} } diff --git a/man/details_rand_forest_aorsf.Rd b/man/details_rand_forest_aorsf.Rd index c263f25ad..8b2124cdc 100644 --- a/man/details_rand_forest_aorsf.Rd +++ b/man/details_rand_forest_aorsf.Rd @@ -9,16 +9,16 @@ trees, each de-correlated from the others. The final prediction uses all predictions from the individual trees and combines them. } \details{ -For this engine, there are multiple modes: classification, regression, -and censored regression +For this engine, there are multiple modes: censored regression, +classification, and regression \subsection{Tuning Parameters}{ This model has 3 tuning parameters: \itemize{ -\item \code{mtry}: # Randomly Selected Predictors (type: integer, default: -ceiling(sqrt(n_predictors))) \item \code{trees}: # Trees (type: integer, default: 500L) \item \code{min_n}: Minimal Node Size (type: integer, default: 5L) +\item \code{mtry}: # Randomly Selected Predictors (type: integer, default: +ceiling(sqrt(n_predictors))) } Additionally, this model has one engine-specific tuning parameter: @@ -119,19 +119,20 @@ The \code{fit()} and \code{fit_xy()} arguments have arguments called \if{html}{\out{
}}\preformatted{parsnip:::get_from_env("rand_forest_predict") |> dplyr::filter(engine == "aorsf") |> - dplyr::select(mode, type) + dplyr::select(mode, type)|> + print(n = Inf) }\if{html}{\out{
}} \if{html}{\out{
}}\preformatted{## # A tibble: 7 x 2 -## mode type -## -## 1 classification class -## 2 classification prob -## 3 classification raw -## 4 regression numeric -## 5 regression raw -## 6 censored regression time -## # i 1 more row +## mode type +## +## 1 censored regression time +## 2 censored regression survival +## 3 classification class +## 4 classification prob +## 5 classification raw +## 6 regression numeric +## 7 regression raw }\if{html}{\out{
}} } diff --git a/man/details_rand_forest_partykit.Rd b/man/details_rand_forest_partykit.Rd index a6f392a53..4af378e97 100644 --- a/man/details_rand_forest_partykit.Rd +++ b/man/details_rand_forest_partykit.Rd @@ -9,15 +9,15 @@ trees, each independent of the others. The final prediction uses all predictions from the individual trees and combines them. } \details{ -For this engine, there are multiple modes: regression, classification, -and censored regression +For this engine, there are multiple modes: censored regression, +regression, and classification \subsection{Tuning Parameters}{ This model has 3 tuning parameters: \itemize{ +\item \code{trees}: # Trees (type: integer, default: 500L) \item \code{min_n}: Minimal Node Size (type: integer, default: 20L) \item \code{mtry}: # Randomly Selected Predictors (type: integer, default: 5L) -\item \code{trees}: # Trees (type: integer, default: 500L) } } @@ -110,11 +110,11 @@ are not required for this model. \if{html}{\out{
}}\preformatted{## # A tibble: 5 x 2 ## mode type ## -## 1 regression numeric -## 2 classification class -## 3 classification prob -## 4 censored regression time -## 5 censored regression survival +## 1 censored regression time +## 2 censored regression survival +## 3 regression numeric +## 4 classification class +## 5 classification prob }\if{html}{\out{
}} } From db67f2beb59f5c316edb887e25c369492709c5fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=98topepo=E2=80=99?= Date: Sun, 30 Nov 2025 18:10:17 -0500 Subject: [PATCH 5/8] update parsnip add-in code and db --- data/model_db.rda | Bin 2778 -> 3335 bytes inst/add-in/parsnip_model_db.R | 79 ++++++++++++++++++++++++--------- 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/data/model_db.rda b/data/model_db.rda index 8168b7e2265f9e150207ee5a4d16f6ae09319eb7..784b7dc06b87232a70a103a417f9e809b474e460 100644 GIT binary patch literal 3335 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 RXej^U?ntK!5)lc4NB~@_9DD!( literal 2778 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 diff --git a/inst/add-in/parsnip_model_db.R b/inst/add-in/parsnip_model_db.R index b3cf38b0b..c5bec0d66 100644 --- a/inst/add-in/parsnip_model_db.R +++ b/inst/add-in/parsnip_model_db.R @@ -9,28 +9,66 @@ library(usethis) # also requires installation of: packages <- c( "parsnip", - "discrim", - "plsmod", - "rules", - "baguette", - "poissonreg", - "multilevelmod", - "modeltime", - "modeltime.gluonts" + parsnip:::extensions(), + "modeltime" + # "modeltime.gluonts" # required python packages to create spec ) +loaded <- map(packages, library, character.only = TRUE) + # ------------------------------------------------------------------------------ -# Detects model specifications via their print methods -print_methods <- function(x) { - require(x, character.only = TRUE) - ns <- asNamespace(ns = x) - mthds <- ls(envir = ns, pattern = "^print\\.") - mthds <- gsub("^print\\.", "", mthds) - purrr::map(mthds, get_engines) |> +get_model <- function(x) { + res <- get_from_env(x) + if (!is.null(res)) { + res <- dplyr::mutate(res, model = x) + } + res +} + +get_packages <- function(x) { + res <- get_from_env(paste0(x, "_pkgs")) + if (is.null(res)) { + return(res) + } + res <- + res |> + tidyr::unnest(pkg) |> + dplyr::mutate( + model = x + ) + + res +} + +get_models <- function() { + res <- ls(envir = get_model_env(), pattern = "_fit$") + models <- gsub("_fit$", "", res) + models <- + purrr::map(models, get_model) |> + purrr::list_rbind() + + # get source package + pkgs <- gsub("_fit$", "_pkgs", res) + pkgs <- + unique(models$model) |> + purrr::map(get_packages) |> purrr::list_rbind() |> - dplyr::mutate(package = x) + dplyr::filter(pkg %in% packages) + dplyr::left_join(models, pkgs, by = dplyr::join_by(engine, mode, model)) |> + dplyr::rename(package = pkg) |> + dplyr::mutate( + package = dplyr::if_else(is.na(package), "parsnip", package), + call_from_parsnip = package %in% parsnip:::extensions(), + caller_package = dplyr::if_else( + call_from_parsnip, + "parsnip", + package + ) + ) } + + get_engines <- function(x) { eng <- try(parsnip::show_engines(x), silent = TRUE) if (inherits(eng, "try-error")) { @@ -77,8 +115,8 @@ get_tunable_param <- function(mode, package, model, engine) { # ------------------------------------------------------------------------------ model_db <- - purrr::map(packages, print_methods) |> - purrr::list_rbind() |> + get_models() |> + dplyr::filter(mode %in% c("regression", "classification")) |> dplyr::filter(engine != "liquidSVM") |> dplyr::filter(model != "surv_reg") |> dplyr::filter(engine != "spark") |> @@ -98,9 +136,10 @@ model_db <- dplyr::left_join(model_db, num_modes, by = c("package", "model", "engine")) |> dplyr::mutate( parameters = purrr::pmap( - list(mode, package, model, engine), + list(mode, caller_package, model, engine), get_tunable_param ) - ) + ) |> + dplyr::select(-call_from_parsnip, -caller_package) usethis::use_data(model_db, overwrite = TRUE) From 0e6cad5b63bca612aeedbd5a0d76fe98f013e83a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=98topepo=E2=80=99?= Date: Mon, 1 Dec 2025 12:33:34 -0500 Subject: [PATCH 6/8] added ORCID --- DESCRIPTION | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 44d20ca1a..0e2119f76 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,7 +2,8 @@ Package: parsnip Title: A Common API to Modeling and Analysis Functions Version: 1.4.0 Authors@R: c( - person("Max", "Kuhn", , "max@posit.co", role = c("aut", "cre")), + person("Max", "Kuhn", , "max@posit.co", role = c("cre", "aut"), + comment = c(ORCID = "0000-0003-2402-136X")), person("Davis", "Vaughan", , "davis@posit.co", role = "aut"), person("Emil", "Hvitfeldt", , "emil.hvitfeldt@posit.co", role = "ctb"), person("Posit Software, PBC", role = c("cph", "fnd"), From e8a5314f7b81a0b6b694603daa6ebd9675b9ebce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=98topepo=E2=80=99?= Date: Mon, 1 Dec 2025 12:46:21 -0500 Subject: [PATCH 7/8] keras install in CI --- .github/workflows/R-CMD-check.yaml | 7 +++---- .github/workflows/test-coverage.yaml | 15 +++------------ 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 150ed5e7a..135e8834f 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -67,11 +67,10 @@ jobs: with: python-version: 3.11 - - name: Install TensorFlow + - name: Install TensorFlow/Keras run: | - reticulate::virtualenv_create('r-reticulate', python='3.11') - reticulate::use_virtualenv('r-reticulate') - tensorflow::install_tensorflow(version='2.16') + install.packages(c("keras3")) + keras3::install_keras() shell: Rscript {0} - uses: r-lib/actions/check-r-package@v2 diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index 6e56ef9a4..b29fc83bf 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -27,19 +27,10 @@ jobs: extra-packages: any::covr, any::xml2 needs: coverage - - name: Install dev reticulate - run: pak::pkg_install('rstudio/reticulate') - shell: Rscript {0} - - - name: Install Miniconda - run: | - reticulate::install_miniconda() - shell: Rscript {0} - - - name: Install TensorFlow + - name: Install TensorFlow/Keras run: | - reticulate::conda_create('r-reticulate', packages = c('python==3.11')) - tensorflow::install_tensorflow(version='2.16') + install.packages(c("keras3")) + keras3::install_keras() shell: Rscript {0} - name: Test coverage From aa11c691506ddd409b1671e79dae0a400fb3c84b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=98topepo=E2=80=99?= Date: Mon, 1 Dec 2025 13:00:59 -0500 Subject: [PATCH 8/8] skip to next version --- tests/testthat/test-fit_interfaces.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-fit_interfaces.R b/tests/testthat/test-fit_interfaces.R index 440ab9a12..31b084582 100644 --- a/tests/testthat/test-fit_interfaces.R +++ b/tests/testthat/test-fit_interfaces.R @@ -172,7 +172,7 @@ test_that("overhead of parsnip interface is minimal (#1071)", { skip_on_cran() skip_on_covr() skip_if_not_installed("bench") - skip_if_not_installed("parsnip", minimum_version = "1.4.0") + skip_if_not_installed("parsnip", minimum_version = "1.5.0") bm <- bench::mark( time_engine = lm(mpg ~ ., mtcars),