Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,16 @@ This version introduces source code and unit tests for new engines and dials:

Coordinated with [parsnip PR #1384](https://github.com/tidymodels/parsnip/pull/1384).

### linear prediction type
### new prediction types

Linear predictions are enabled for the `clm`, `lrm`, `orm`, `vglm`, and `ordinalNet` ordinal regression engines and for the `vgam` generalized additive model engine.
Linear predictions via `predict_linear_pred()` are enabled for the `clm`, `lrm`, `orm`, `vglm`, and `ordinalNet` ordinal regression engines and for the `vgam` generalized additive model engine.
They consistently return a single column of linear predictors (without threshold contributions).

Coordinated with [parsnip PR #1391](https://github.com/tidymodels/parsnip/pull/1391).

Confidence interval predictions via `predict_confint()` are enabled for the `clm` engine.
They return pairs of columns containing pointwise intervals for each class probability.

### threshold structure and parallel regression model arguments

The `threshold_structure` model argument for `ordinal_reg()` controls what constraints, if any, are imposed on the ordered thresholds.
Expand Down
1 change: 0 additions & 1 deletion R/decision_tree-data.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
# `rpartScore::rpartScore` components

make_decision_tree_rpartScore <- function() {

parsnip::set_model_engine("decision_tree", "classification", "rpartScore")
parsnip::set_dependency(
"decision_tree",
Expand Down
7 changes: 5 additions & 2 deletions R/decision_tree-rpartScore.R
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ rpartScore_wrapper <- function(formula, data, ...) {
data[[lhs]] <- as.integer(data[[lhs]])
# execute call on modified inputs
cl <- rlang::call2(
.fn = "rpartScore", .ns = "rpartScore",
formula = rlang::expr(formula), data = rlang::expr(data), ...
.fn = "rpartScore",
.ns = "rpartScore",
formula = rlang::expr(formula),
data = rlang::expr(data),
...
)
rlang::eval_tidy(cl)
}
35 changes: 15 additions & 20 deletions R/gen_additive_mod-data.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
# `VGAM::vgam` components

make_gen_additive_mod_vgam <- function() {

parsnip::set_model_engine("gen_additive_mod", "classification", "vgam")
parsnip::set_dependency(
"gen_additive_mod",
Expand Down Expand Up @@ -94,12 +93,11 @@ make_gen_additive_mod_vgam <- function() {
pre = NULL,
post = predict_VGAM_class_post,
func = c(fun = "predict", pkg = "VGAM"),
args =
list(
object = quote(object$fit),
newdata = quote(new_data),
type = "response"
)
args = list(
object = quote(object$fit),
newdata = quote(new_data),
type = "response"
)
)
)

Expand All @@ -112,12 +110,11 @@ make_gen_additive_mod_vgam <- function() {
pre = NULL,
post = predict_VGAM_prob_post,
func = c(fun = "predict", pkg = "VGAM"),
args =
list(
object = quote(object$fit),
newdata = quote(new_data),
type = "response"
)
args = list(
object = quote(object$fit),
newdata = quote(new_data),
type = "response"
)
)
)

Expand All @@ -133,15 +130,13 @@ make_gen_additive_mod_vgam <- function() {
tibble::tibble(.pred_linear_pred = unname(beta_x))
},
func = c(fun = "predict", pkg = "VGAM"),
args =
list(
object = quote(object$fit),
newdata = quote(new_data),
type = "link"
)
args = list(
object = quote(object$fit),
newdata = quote(new_data),
type = "link"
)
)
)

}

# nocov end
96 changes: 62 additions & 34 deletions R/ordinal_reg-VGAM.R
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,14 @@
#' }#VGAM>1.1-9
#' @export
VGAM_vglm_wrapper <- function(
formula, data,
family = "cumulative",
link = "logitlink",
parallel = FALSE,
Thresh = NULL,
...,
call = rlang::caller_env()
formula,
data,
family = "cumulative",
link = "logitlink",
parallel = FALSE,
Thresh = NULL,
...,
call = rlang::caller_env()
) {
rlang::check_installed("VGAM")
VGAM_1_1_9 <- utils::packageVersion("VGAM") == package_version("1.1.9")
Expand All @@ -149,18 +150,26 @@ VGAM_vglm_wrapper <- function(
# execute nested call on modified inputs
family_call <- if (VGAM_1_1_9) {
rlang::call2(
.fn = family, .ns = "VGAM",
link = link, parallel = parallel, threshold = Thresh
.fn = family,
.ns = "VGAM",
link = link,
parallel = parallel,
threshold = Thresh
)
} else {
rlang::call2(
.fn = family, .ns = "VGAM",
link = link, parallel = parallel, Thresh = Thresh
.fn = family,
.ns = "VGAM",
link = link,
parallel = parallel,
Thresh = Thresh
)
}
cl <- rlang::call2(
.fn = "vglm", .ns = "VGAM",
formula = rlang::expr(formula), data = rlang::expr(data),
.fn = "vglm",
.ns = "VGAM",
formula = rlang::expr(formula),
data = rlang::expr(data),
family = family_call,
...
)
Expand All @@ -170,13 +179,14 @@ VGAM_vglm_wrapper <- function(
#' @rdname VGAM_vglm_wrapper
#' @export
VGAM_vgam_wrapper <- function(
formula, data,
family = "cumulative",
link = "logitlink",
parallel = FALSE,
Thresh = NULL,
...,
call = rlang::caller_env()
formula,
data,
family = "cumulative",
link = "logitlink",
parallel = FALSE,
Thresh = NULL,
...,
call = rlang::caller_env()
) {
rlang::check_installed("VGAM")
VGAM_1_1_9 <- utils::packageVersion("VGAM") == package_version("1.1.9")
Expand All @@ -194,18 +204,26 @@ VGAM_vgam_wrapper <- function(
# execute nested call on modified inputs
family_call <- if (VGAM_1_1_9) {
rlang::call2(
.fn = family, .ns = "VGAM",
link = link, parallel = parallel, threshold = Thresh
.fn = family,
.ns = "VGAM",
link = link,
parallel = parallel,
threshold = Thresh
)
} else {
rlang::call2(
.fn = family, .ns = "VGAM",
link = link, parallel = parallel, Thresh = Thresh
.fn = family,
.ns = "VGAM",
link = link,
parallel = parallel,
Thresh = Thresh
)
}
cl <- rlang::call2(
.fn = "vgam", .ns = "VGAM",
formula = rlang::expr(formula), data = rlang::expr(data),
.fn = "vgam",
.ns = "VGAM",
formula = rlang::expr(formula),
data = rlang::expr(data),
family = family_call,
...
)
Expand Down Expand Up @@ -256,17 +274,26 @@ match_ordinal_family <- function(family, call = rlang::caller_env()) {
}

match_ordinal_link_VGAM <- function(link, call = rlang::caller_env()) {
if (! is.character(link)) {
if (!is.character(link)) {
return(link)
}
check_string(link, arg = "ordinal_link", call = call)

if (
# keep native values
! link %in% c(
"logitlink", "probitlink", "logloglink", "clogloglink", "cauchitlink",
"foldsqrtlink", "logclink", "gordlink", "pordlink", "nbordlink"
)
!link %in%
c(
"logitlink",
"probitlink",
"logloglink",
"clogloglink",
"cauchitlink",
"foldsqrtlink",
"logclink",
"gordlink",
"pordlink",
"nbordlink"
)
) {
# modify standardized values
link <- rlang::arg_match0(
Expand Down Expand Up @@ -294,10 +321,11 @@ match_ordinal_link_VGAM <- function(link, call = rlang::caller_env()) {
}

match_threshold_structure_VGAM <- function(
Thresh, v_1_1_9 = FALSE,
Thresh,
v_1_1_9 = FALSE,
call = rlang::caller_env()
) {
if (! is.character(Thresh)) {
if (!is.character(Thresh)) {
return(Thresh)
}
check_string(Thresh, arg = "threshold_structure", call = call)
Expand All @@ -310,7 +338,7 @@ match_threshold_structure_VGAM <- function(

if (
# keep native values
! Thresh %in% native_vals
!Thresh %in% native_vals
) {
# modify standardized values
Thresh <- rlang::arg_match0(
Expand Down
35 changes: 28 additions & 7 deletions R/ordinal_reg-clm.R
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ clm_wrapper <- function(
}

args <- c(formulas, list(data = data))
if (! is.null(weights)) {
if (!is.null(weights)) {
args$weights <- weights
}
if (! is.null(link)) {
if (!is.null(link)) {
args$link <- match_ordinal_link_clm(link, call = call)
}
if (! is.null(threshold)) {
if (!is.null(threshold)) {
threshold <- switch(
threshold,
flexible = "flexible",
Expand All @@ -85,18 +85,18 @@ clm_wrapper <- function(
# printing the fit shows the formulas and engine arguments that were used.
res$call <- rlang::call2(
"clm",
!!! formulas,
!!!formulas,
data = rlang::sym("data"),
!!! arg_exprs,
!!! dot_exprs,
!!!arg_exprs,
!!!dot_exprs,
.ns = "ordinal"
)

res
}

match_ordinal_link_clm <- function(link, call = rlang::caller_env()) {
if (! is.character(link)) {
if (!is.character(link)) {
return(link)
}
check_string(link, arg = "ordinal_link", call = call)
Expand Down Expand Up @@ -150,3 +150,24 @@ predict_clm_pre <- function(new_data, object) {
}
new_data
}

predict_clm_confint_post <- function(x, object) {
lvl <- object$lvl
bounds <- vector("list", 2L * length(lvl))
for (i in seq_along(lvl)) {
bounds[[2L * i - 1L]] <- unname(x$lwr[, i])
bounds[[2L * i]] <- unname(x$upr[, i])
}
names(bounds) <- c(
rbind(paste0(".pred_lower_", lvl), paste0(".pred_upper_", lvl))
)
res <- tibble::as_tibble(bounds)

if (isTRUE(object$spec$method$pred$conf_int$extras$std_error)) {
errors <- lapply(seq_along(lvl), function(i) unname(x$se.fit[, i]))
names(errors) <- paste0(".std_error_", lvl)
res <- tibble::as_tibble(c(bounds, errors))
}

res
}
Loading
Loading