diff --git a/DESCRIPTION b/DESCRIPTION index 2dfebbcd..59206104 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -29,7 +29,7 @@ Description: Fit, interpret, and make predictions with oblique random survival f License: MIT + file LICENSE Encoding: UTF-8 LazyData: true -Roxygen: list(markdown = TRUE, roclets = c ("namespace", "rd")) +Roxygen: list(markdown = TRUE) RoxygenNote: 7.2.3 LinkingTo: Rcpp, @@ -38,8 +38,9 @@ Imports: Rcpp, data.table, utils, - collapse, - R6 + collapse, + R6, + lifecycle URL: https://github.com/ropensci/aorsf, https://docs.ropensci.org/aorsf/ BugReports: https://github.com/ropensci/aorsf/issues/ diff --git a/NAMESPACE b/NAMESPACE index 9d2fee38..617adbae 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -5,10 +5,14 @@ S3method(predict,ObliqueForest) S3method(print,ObliqueForest) S3method(print,orsf_summary_uni) export(orsf) +export(orsf_control) +export(orsf_control_classification) export(orsf_control_cph) export(orsf_control_custom) export(orsf_control_fast) export(orsf_control_net) +export(orsf_control_regression) +export(orsf_control_survival) export(orsf_ice_inb) export(orsf_ice_new) export(orsf_ice_oob) @@ -29,4 +33,5 @@ import(R6) import(data.table) importFrom(Rcpp,sourceCpp) importFrom(collapse,"%==%") +importFrom(lifecycle,deprecated) useDynLib(aorsf, .registration = TRUE) diff --git a/R/aorsf-package.R b/R/aorsf-package.R index 40ce1538..8199ff7e 100644 --- a/R/aorsf-package.R +++ b/R/aorsf-package.R @@ -6,8 +6,9 @@ # The following block is used by usethis to automatically manage # roxygen namespace tags. Modify with care! ## usethis namespace: start -#' @importFrom Rcpp sourceCpp #' @importFrom collapse %==% +#' @importFrom lifecycle deprecated +#' @importFrom Rcpp sourceCpp #' @useDynLib aorsf, .registration = TRUE ## usethis namespace: end NULL diff --git a/R/orsf_R6.R b/R/orsf_R6.R index 159f3182..761c7012 100644 --- a/R/orsf_R6.R +++ b/R/orsf_R6.R @@ -407,7 +407,8 @@ ObliqueForest <- R6::R6Class( private$check_pred_horizon(pred_horizon, boundary_checks, pred_type) - if(is.null(pred_horizon)) pred_horizon <- 1 + pred_horizon <- pred_horizon %||% self$pred_horizon %||% 1 + pred_horizon_order <- order(pred_horizon) pred_horizon_ordered <- pred_horizon[pred_horizon_order] @@ -435,11 +436,11 @@ ObliqueForest <- R6::R6Class( private$prep_x() # y and w do not need to be prepped for prediction, # but they need to match orsf_cpp()'s expectations - private$y <- matrix(0, nrow = nrow(private$x), ncol = 1) + private$prep_y(placeholder = TRUE) private$w <- rep(1, nrow(private$x)) - if(oobag){ private$sort_inputs() } + if(oobag){ private$sort_inputs(sort_y = FALSE) } # the values in pred_spec need to be centered & scaled to match x_new, # which is also centered and scaled @@ -660,6 +661,8 @@ ObliqueForest <- R6::R6Class( if(self$tree_type == 'classification'){ setnames(out, old = 'pred_horizon', new = 'class') + out[, class := factor(class, levels = self$class_levels)] + setkey(out, class) } if(self$tree_type == 'survival' && pred_type != 'mort') @@ -878,13 +881,14 @@ ObliqueForest <- R6::R6Class( # To avoid this: include a DT[] after the last := in your function. pd_output[] - setcolorder(pd_output, c('variable', - 'importance', - 'value', - 'mean', - 'medn', - 'lwr', - 'upr')) + new_order <- c('variable', 'importance', 'value', + 'mean', 'medn', 'lwr', 'upr') + + if(self$tree_type == 'classification'){ + new_order <- insert_vals(new_order, 2, 'class') + } + + setcolorder(pd_output, new_order) structure( .Data = list(dt = pd_output, @@ -2316,14 +2320,14 @@ ObliqueForest <- R6::R6Class( }, - prep_y = function(){ + prep_y = function(placeholder = FALSE){ private$y <- select_cols(self$data, private$data_names$y) - if(self$na_action == 'omit') + if(self$na_action == 'omit' && !placeholder) private$y <- private$y[private$data_rows_complete, ] - private$prep_y_internal() + private$prep_y_internal(placeholder) }, @@ -2686,11 +2690,16 @@ ObliqueForestSurvival <- R6::R6Class( }, - sort_inputs = function(){ + sort_inputs = function(sort_x = TRUE, + sort_y = TRUE, + sort_w = TRUE){ - private$x <- private$x[private$data_row_sort, , drop = FALSE] - private$y <- private$y[private$data_row_sort, , drop = FALSE] - private$w <- private$w[private$data_row_sort] + if(sort_x) + private$x <- private$x[private$data_row_sort, , drop = FALSE] + if(sort_y) + private$y <- private$y[private$data_row_sort, , drop = FALSE] + if(sort_w) + private$w <- private$w[private$data_row_sort] }, @@ -2698,6 +2707,10 @@ ObliqueForestSurvival <- R6::R6Class( self$tree_type <- "survival" + if(!is.function(self$control$lincomb_R_function) && + self$control$lincomb_type == 'net'){ + self$control$lincomb_R_function <- penalized_cph + } self$split_rule <- self$split_rule %||% 'logrank' self$pred_type <- self$pred_type %||% 'surv' @@ -2761,7 +2774,13 @@ ObliqueForestSurvival <- R6::R6Class( } }, - prep_y_internal = function(){ + prep_y_internal = function(placeholder = FALSE){ + + + if(placeholder){ + private$y <- matrix(0, ncol = 2, nrow = 1) + return() + } y <- private$y cols <- names(y) @@ -2979,6 +2998,11 @@ ObliqueForestClassification <- R6::R6Class( self$tree_type <- "classification" + if(!is.function(self$control$lincomb_R_function) && + self$control$lincomb_type == 'net'){ + self$control$lincomb_R_function <- penalized_logreg + } + self$split_rule <- self$split_rule %||% 'gini' self$pred_type <- self$pred_type %||% 'prob' self$split_min_stat <- self$split_min_stat %||% @@ -3003,7 +3027,12 @@ ObliqueForestClassification <- R6::R6Class( }, - prep_y_internal = function(){ + prep_y_internal = function(placeholder = FALSE){ + + if(placeholder){ + private$y <- matrix(0, ncol = self$n_class-1, nrow = 1) + return() + } # y is always 1 column for classification (right?) y <- private$y[[1]] diff --git a/R/orsf_control.R b/R/orsf_control.R index b6908047..b85e5e72 100644 --- a/R/orsf_control.R +++ b/R/orsf_control.R @@ -72,6 +72,8 @@ orsf_control_fast <- function(method = 'efron', #' to create linear combinations of predictor variables #' while fitting an [orsf] model. #' +#' `r lifecycle::badge('superseded')` +#' #' @inheritParams orsf_control_fast #' #' @param eps (_double_) When using Newton Raphson scoring to identify @@ -85,6 +87,7 @@ orsf_control_fast <- function(method = 'efron', #' (see `eps` above) or the number of attempted iterations is equal to #' `iter_max`. #' +#' #' @return an object of class `'orsf_control'`, which should be used as #' an input for the `control` argument of [orsf]. #' @@ -117,6 +120,11 @@ orsf_control_cph <- function(method = 'efron', iter_max = 20, ...){ + lifecycle::deprecate_warn( + when = "0.1.2", + "orsf_control_custom()", + details = "Please use the appropriate survival, classification, or regression control function instead. E.g., `orsf_control_survival(method = your_function)`" + ) method <- tolower(method) @@ -144,6 +152,8 @@ orsf_control_cph <- function(method = 'efron', #' Use regularized Cox proportional hazard models to identify linear #' combinations of input variables while fitting an [orsf] model. #' +#' `r lifecycle::badge('superseded')` +#' #' @param alpha (_double_) The elastic net mixing parameter. A value of 1 gives the #' lasso penalty, and a value of 0 gives the ridge penalty. If multiple #' values of alpha are given, then a penalized model is fit using each @@ -153,6 +163,7 @@ orsf_control_cph <- function(method = 'efron', #' #' @param ... `r roxy_dots()` #' +#' #' @inherit orsf_control_cph return #' #' @details @@ -169,8 +180,6 @@ orsf_control_cph <- function(method = 'efron', #' #' `r roxy_cite_simon_2011()` #' -#' -#' #' @examples #' #' # orsf_control_net() is considerably slower than orsf_control_cph(), @@ -186,6 +195,12 @@ orsf_control_net <- function(alpha = 1/2, df_target = NULL, ...){ + lifecycle::deprecate_warn( + when = "0.1.2", + "orsf_control_custom()", + details = "Please use the appropriate survival, classification, or regression control function instead. E.g., `orsf_control_survival(method = your_function)`" + ) + check_dots(list(...), orsf_control_net) check_control_net(alpha, df_target) @@ -202,6 +217,8 @@ orsf_control_net <- function(alpha = 1/2, #' Custom ORSF control #' +#' `r lifecycle::badge('superseded')` +#' #' @param beta_fun (_function_) a function to define coefficients used #' in linear combinations of predictor variables. `beta_fun` must accept #' three inputs named `x_node`, `y_node` and `w_node`, and should expect @@ -219,14 +236,22 @@ orsf_control_net <- function(alpha = 1/2, #' #' @inherit orsf_control_cph return #' +#' #' @export #' +#' #' @family orsf_control #' #' @includeRmd Rmd/orsf_control_custom_examples.Rmd orsf_control_custom <- function(beta_fun, ...){ + lifecycle::deprecate_warn( + when = "0.1.2", + "orsf_control_custom()", + details = "Please use the appropriate survival, classification, or regression control function instead. E.g., `orsf_control_survival(method = your_function)`" + ) + check_dots(list(...), .f = orsf_control_custom) check_beta_fun(beta_fun) @@ -305,7 +330,7 @@ orsf_control_custom <- function(beta_fun, ...){ #' #' @param ... `r roxy_dots()` #' -#' @noRd +#' @family orsf_control #' #' @details #' @@ -327,7 +352,7 @@ orsf_control_custom <- function(beta_fun, ...){ #' - `lincomb_ties_method`: method for ties in survival time #' - `lincomb_R_function`: R function for custom splits #' -#' +#' @export #' orsf_control <- function(tree_type, method, @@ -339,14 +364,118 @@ orsf_control <- function(tree_type, epsilon, ...){ + check_arg_type(arg_value = method, + arg_name = 'method', + expected_type = c('character', 'function')) + custom <- is.function(method) + if(!custom){ + + check_arg_is_valid(arg_value = method, + arg_name = 'method', + valid_options = c("glm", "net")) + + check_arg_length(arg_value = method, + arg_name = 'method', + expected_length = 1) + + } else { + + check_beta_fun(method) + + } + + check_arg_type(arg_value = scale_x, + arg_name = 'scale_x', + expected_type = 'logical') + + check_arg_length(arg_value = scale_x, + arg_name = 'scale_x', + expected_length = 1) + + if(!is.null(ties)){ + + check_arg_type(arg_value = ties, + arg_name = 'ties', + expected_type = 'character') + + check_arg_is_valid(arg_value = ties, + arg_name = 'ties', + valid_options = c("breslow", "efron")) + + } + + check_arg_type(arg_value = net_mix, + arg_name = 'net_mix', + expected_type = 'numeric') + + check_arg_gteq(arg_value = net_mix, + arg_name = 'net_mix', + bound = 0) + + check_arg_lteq(arg_value = net_mix, + arg_name = 'net_mix', + bound = 1) + + check_arg_length(arg_value = net_mix, + arg_name = 'net_mix', + expected_length = 1) + + if(!is.null(target_df)){ + + check_arg_type(arg_value = target_df, + arg_name = 'target_df', + expected_type = 'numeric') + + check_arg_is_integer(arg_value = target_df, + arg_name = 'target_df') + + } + + + check_arg_type(arg_value = max_iter, + arg_name = 'max_iter', + expected_type = 'numeric') + + check_arg_is_integer(arg_value = max_iter, + arg_name = 'max_iter') + + check_arg_gteq(arg_value = max_iter, + arg_name = 'max_iter', + bound = 1) + + check_arg_length(arg_value = max_iter, + arg_name = 'max_iter', + expected_length = 1) + + check_arg_type(arg_value = epsilon, + arg_name = 'epsilon', + expected_type = 'numeric') + + check_arg_gt(arg_value = epsilon, + arg_name = 'epsilon', + bound = 0) + + check_arg_length(arg_value = epsilon, + arg_name = 'epsilon', + expected_length = 1) + if(custom){ + lincomb_R_function <- method + } else if (method == 'net') { - lincomb_R_function <- penalized_cph + + lincomb_R_function <- switch(tree_type, + 'survival' = penalized_cph, + 'classification' = penalized_logreg, + 'unknown' = 'unknown') + } else { + lincomb_R_function <- function(x) x + } structure( @@ -367,7 +496,8 @@ orsf_control <- function(tree_type, } - +#' @rdname orsf_control +#' @export orsf_control_classification <- function(method = 'glm', scale_x = TRUE, net_mix = 0.5, @@ -390,7 +520,8 @@ orsf_control_classification <- function(method = 'glm', } - +#' @rdname orsf_control +#' @export orsf_control_regression <- function(method = 'glm', scale_x = TRUE, net_mix = 0.5, @@ -413,7 +544,8 @@ orsf_control_regression <- function(method = 'glm', } - +#' @rdname orsf_control +#' @export orsf_control_survival <- function(method = 'glm', scale_x = TRUE, ties = 'efron', diff --git a/R/orsf_print.R b/R/orsf_print.R index 77c2eb69..29e98b4c 100644 --- a/R/orsf_print.R +++ b/R/orsf_print.R @@ -35,7 +35,6 @@ print.ObliqueForest <- function(x, ...){ x$print() - invisible(x) } diff --git a/R/orsf_summary.R b/R/orsf_summary.R index ed60d6df..32da105a 100644 --- a/R/orsf_summary.R +++ b/R/orsf_summary.R @@ -109,10 +109,15 @@ print.orsf_summary_uni <- function(x, n_variables = NULL, ...){ 'prob' = "Probability" ) - msg_btm <- paste("Predicted", tolower(pred_label), - "at time t =", x$pred_horizon, - "for top", n_variables, - "predictors") + extra_surv_text <- "" + + if(!is.null(x$pred_horizon)) + extra_surv_text <- paste0("at time t = ", x$pred_horizon, " ") + + msg_btm <- paste0( + "Predicted ", tolower(pred_label), " ", extra_surv_text, + "for top ", n_variables, " predictors" + ) .sd_orig <- c("value", "mean", diff --git a/R/penalized_cph.R b/R/penalized_cph.R index 733d09c5..33663b0a 100644 --- a/R/penalized_cph.R +++ b/R/penalized_cph.R @@ -22,6 +22,19 @@ #' alpha = 1/2, #' df_target = 2 #' ) +#' +#' penalized_logreg( +#' x_node = as.matrix(penguins_orsf[, c('bill_length_mm', +#' 'bill_depth_mm', +#' 'flipper_length_mm', +#' 'body_mass_g')]), +#' y_node = as.matrix(as.numeric(penguins_orsf$species == 'Adelie')), +#' w_node = rep(1, nrow(penguins_orsf)), +#' alpha = 1/2, +#' df_target = 2 +#' ) + + penalized_cph <- function(x_node, y_node, @@ -31,13 +44,47 @@ penalized_cph <- function(x_node, colnames(y_node) <- c('time', 'status') + penalized_fitter(x_node = x_node, + y_node = y_node, + w_node = w_node, + alpha = alpha, + df_target = df_target, + family = "cox") + +} + +penalized_logreg <- function(x_node, + y_node, + w_node, + alpha, + df_target){ + + y_node <- as.factor(y_node) + w_node <- as.numeric(w_node) + + penalized_fitter(x_node = x_node, + y_node = y_node, + w_node = w_node, + alpha = alpha, + df_target = df_target, + family = "binomial") + +} + +penalized_fitter <- function(x_node, + y_node, + w_node, + alpha, + df_target, + family){ + suppressWarnings( fit <- try( glmnet::glmnet(x = x_node, y = y_node, weights = w_node, alpha = alpha, - family = "cox"), + family = family), silent = TRUE ) ) diff --git a/R/round_magnitude.R b/R/round_magnitude.R index ba46e8e9..a39fb3ff 100644 --- a/R/round_magnitude.R +++ b/R/round_magnitude.R @@ -19,7 +19,7 @@ round_magnitude <- function(x){ # take absolute value to round based on magnitude x_abs <- abs(x) - breaks <- c(0, 1, 10, Inf) + breaks <- c(0, 10, 100, Inf) decimals <- c(2, 1, 0) # x_cuts create boundary categories for rounding diff --git a/man/figures/lifecycle-archived.svg b/man/figures/lifecycle-archived.svg new file mode 100644 index 00000000..745ab0c7 --- /dev/null +++ b/man/figures/lifecycle-archived.svg @@ -0,0 +1,21 @@ + diff --git a/man/figures/lifecycle-defunct.svg b/man/figures/lifecycle-defunct.svg new file mode 100644 index 00000000..d5c9559e --- /dev/null +++ b/man/figures/lifecycle-defunct.svg @@ -0,0 +1,21 @@ + diff --git a/man/figures/lifecycle-deprecated.svg b/man/figures/lifecycle-deprecated.svg new file mode 100644 index 00000000..b61c57c3 --- /dev/null +++ b/man/figures/lifecycle-deprecated.svg @@ -0,0 +1,21 @@ + diff --git a/man/figures/lifecycle-experimental.svg b/man/figures/lifecycle-experimental.svg new file mode 100644 index 00000000..5d88fc2c --- /dev/null +++ b/man/figures/lifecycle-experimental.svg @@ -0,0 +1,21 @@ + diff --git a/man/figures/lifecycle-maturing.svg b/man/figures/lifecycle-maturing.svg new file mode 100644 index 00000000..897370ec --- /dev/null +++ b/man/figures/lifecycle-maturing.svg @@ -0,0 +1,21 @@ + diff --git a/man/figures/lifecycle-questioning.svg b/man/figures/lifecycle-questioning.svg new file mode 100644 index 00000000..7c1721d0 --- /dev/null +++ b/man/figures/lifecycle-questioning.svg @@ -0,0 +1,21 @@ + diff --git a/man/figures/lifecycle-soft-deprecated.svg b/man/figures/lifecycle-soft-deprecated.svg new file mode 100644 index 00000000..9c166ff3 --- /dev/null +++ b/man/figures/lifecycle-soft-deprecated.svg @@ -0,0 +1,21 @@ + diff --git a/man/figures/lifecycle-stable.svg b/man/figures/lifecycle-stable.svg new file mode 100644 index 00000000..9bf21e76 --- /dev/null +++ b/man/figures/lifecycle-stable.svg @@ -0,0 +1,29 @@ + diff --git a/man/figures/lifecycle-superseded.svg b/man/figures/lifecycle-superseded.svg new file mode 100644 index 00000000..db8d757f --- /dev/null +++ b/man/figures/lifecycle-superseded.svg @@ -0,0 +1,21 @@ + diff --git a/man/orsf_control.Rd b/man/orsf_control.Rd new file mode 100644 index 00000000..8d41dde5 --- /dev/null +++ b/man/orsf_control.Rd @@ -0,0 +1,147 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/orsf_control.R +\name{orsf_control} +\alias{orsf_control} +\alias{orsf_control_classification} +\alias{orsf_control_regression} +\alias{orsf_control_survival} +\title{Oblique random forest control} +\usage{ +orsf_control( + tree_type, + method, + scale_x, + ties, + net_mix, + target_df, + max_iter, + epsilon, + ... +) + +orsf_control_classification( + method = "glm", + scale_x = TRUE, + net_mix = 0.5, + target_df = NULL, + max_iter = 20, + epsilon = 1e-09, + ... +) + +orsf_control_regression( + method = "glm", + scale_x = TRUE, + net_mix = 0.5, + target_df = NULL, + max_iter = 20, + epsilon = 1e-09, + ... +) + +orsf_control_survival( + method = "glm", + scale_x = TRUE, + ties = "efron", + net_mix = 0.5, + target_df = NULL, + max_iter = 20, + epsilon = 1e-09, + ... +) +} +\arguments{ +\item{tree_type}{(\emph{character}) the type of tree. Valid options are +\itemize{ +\item "classification", i.e., categorical outcomes +\item "regression", i.e., continuous outcomes +\item "survival", i.e., time-to event outcomes +}} + +\item{method}{(\emph{character} or \emph{function}) how to identify linear +linear combinations of predictors. If \code{method} is a character value, +it must be one of: +\itemize{ +\item 'glm': linear, logistic, and cox regression +\item 'net': same as 'glm' but with penalty terms +\item 'pca': principal component analysis +\item 'random': random draw from uniform distribution +} + +If \code{method} is a \emph{function}, it will be used to identify linear +combinations of predictor variables. \code{method} must in this case accept +three inputs named \code{x_node}, \code{y_node} and \code{w_node}, and should expect +the following types and dimensions: +\itemize{ +\item \code{x_node} (\emph{matrix}; \code{n} rows, \code{p} columns) +\item \code{y_node} (\emph{matrix}; \code{n} rows, \code{2} columns) +\item \code{w_node} (\emph{matrix}; \code{n} rows, \code{1} column) +} + +In addition, \code{method} must return a matrix with p rows and 1 column.} + +\item{scale_x}{(\emph{logical}) if \code{TRUE}, values of predictors will be +scaled prior to each instance of finding a linear combination of +predictors, using summary values from the data in the current node +of the decision tree.} + +\item{ties}{(\emph{character}) a character string specifying the method +for tie handling. Only relevant when modeling survival outcomes +and using a method that engages with tied outcome times. +If there are no ties, all the methods are equivalent. Valid options +are 'breslow' and 'efron'. The Efron approximation is the default +because it is more accurate when dealing with tied event times and +has similar computational efficiency compared to the Breslow method.} + +\item{net_mix}{(\emph{double}) The elastic net mixing parameter. A value of 1 +gives the lasso penalty, and a value of 0 gives the ridge penalty. If +multiple values of alpha are given, then a penalized model is fit using +each alpha value prior to splitting a node.} + +\item{target_df}{(\emph{integer}) Preferred number of variables used in each +linear combination. For example, with \code{mtry} of 5 and \code{target_df} of 3, +we sample 5 predictors and look for the best linear combination using +3 of them.} + +\item{max_iter}{(\emph{integer}) iteration continues until convergence +(see \code{eps} above) or the number of attempted iterations is equal to +\code{iter_max}.} + +\item{epsilon}{(\emph{double}) When using most modeling based method, +iteration continues in the algorithm until the relative change in +some kind of objective is less than \code{epsilon}, or the absolute +change is less than \code{sqrt(epsilon)}.} + +\item{...}{Further arguments passed to or from other methods (not currently used).} +} +\value{ +an object of class \code{'orsf_control'}, which should be used as +an input for the \code{control} argument of \link{orsf}. Components are: +\itemize{ +\item \code{tree_type}: type of trees to fit +\item \code{lincomb_type}: method for linear combinations +\item \code{lincomb_eps}: epsilon for convergence +\item \code{lincomb_iter_max}: max iterations +\item \code{lincomb_scale}: to scale or not. +\item \code{lincomb_alpha}: mixing parameter +\item \code{lincomb_df_target}: target degrees of freedom +\item \code{lincomb_ties_method}: method for ties in survival time +\item \code{lincomb_R_function}: R function for custom splits +} +} +\description{ +Oblique random forest control +} +\details{ +Adjust \code{scale_x} \emph{at your own risk}. Setting \code{scale_x = FALSE} will +reduce computation time but will also make the \code{orsf} model dependent +on the scale of your data, which is why the default value is \code{TRUE}. +} +\seealso{ +linear combination control functions +\code{\link{orsf_control_cph}()}, +\code{\link{orsf_control_custom}()}, +\code{\link{orsf_control_fast}()}, +\code{\link{orsf_control_net}()} +} +\concept{orsf_control} diff --git a/man/orsf_control_cph.Rd b/man/orsf_control_cph.Rd index 73d527a5..c1a38efb 100644 --- a/man/orsf_control_cph.Rd +++ b/man/orsf_control_cph.Rd @@ -37,6 +37,8 @@ to create linear combinations of predictor variables while fitting an \link{orsf} model. } \details{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#superseded}{\figure{lifecycle-superseded.svg}{options: alt='[Superseded]'}}}{\strong{[Superseded]}} + code from the \href{https://github.com/therneau/survival/blob/master/src/coxfit6.c}{survival package} was modified to make this routine. @@ -59,6 +61,7 @@ Springer, New York, NY. DOI: 10.1007/978-1-4757-3294-8_3 linear combination control functions \code{\link{orsf_control_custom}()}, \code{\link{orsf_control_fast}()}, -\code{\link{orsf_control_net}()} +\code{\link{orsf_control_net}()}, +\code{\link{orsf_control}()} } \concept{orsf_control} diff --git a/man/orsf_control_custom.Rd b/man/orsf_control_custom.Rd index 93126e5e..921ae356 100644 --- a/man/orsf_control_custom.Rd +++ b/man/orsf_control_custom.Rd @@ -28,7 +28,7 @@ an object of class \code{'orsf_control'}, which should be used as an input for the \code{control} argument of \link{orsf}. } \description{ -Custom ORSF control +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#superseded}{\figure{lifecycle-superseded.svg}{options: alt='[Superseded]'}}}{\strong{[Superseded]}} } \section{Examples}{ Two customized functions to identify linear combinations of predictors @@ -55,8 +55,17 @@ fit_rando <- orsf(pbc_orsf, Surv(time, status) ~ . - id, control = orsf_control_custom(beta_fun = f_rando), n_tree = 500) +}\if{html}{\out{}} + +\if{html}{\out{