Skip to content

Commit a85e508

Browse files
topepohfrick
andauthored
survival time to binary conversion (#973)
* export and document some helpers * move roxygen2 to other file * avoid collating info in description file * update comments for posterity * update news * unit tests and update docs * rename file to match corresponding R file * capture code in snapshot * tweak documentation * update pkgdown index * moving this test to the others in extratests --------- Co-authored-by: Hannah Frick <hannah@rstudio.com>
1 parent 086ad63 commit a85e508

File tree

8 files changed

+150
-2
lines changed

8 files changed

+150
-2
lines changed

NAMESPACE

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,15 @@ export(.convert_form_to_xy_new)
157157
export(.convert_xy_to_form_fit)
158158
export(.convert_xy_to_form_new)
159159
export(.dat)
160+
export(.extract_surv_status)
161+
export(.extract_surv_time)
160162
export(.facts)
161163
export(.lvls)
162164
export(.model_param_name_key)
163165
export(.obs)
164166
export(.organize_glmnet_pred)
165167
export(.preds)
168+
export(.time_as_binary_event)
166169
export(.x)
167170
export(.y)
168171
export(C5.0_train)

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
* For BART models with the `dbarts` engine, `predict()` can now also return the standard error for confidence and prediction intervals (#976).
88

9+
* A few censored regression helper functions were exported: `.extract_surv_status()`, `.extract_surv_time()`, and `.time_as_binary_event()` (#973).
10+
911

1012
# parsnip 1.1.0
1113

R/standalone-survival.R

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# ---
22
# repo: tidymodels/parsnip
33
# file: standalone-survival.R
4-
# last-updated: 2023-02-28
4+
# last-updated: 2023-05-18
55
# license: https://unlicense.org
66
# ---
77

@@ -11,7 +11,9 @@
1111

1212
# 2023-02-28:
1313
# * Initial version
14-
14+
#
15+
# 2023-05-18
16+
# * added time to factor conversion
1517

1618
# @param surv A [survival::Surv()] object
1719
# @details
@@ -20,10 +22,15 @@
2022
#
2123
# `.extract_status()` will return the data as 0/1 even if the original object
2224
# used the legacy encoding of 1/2. See [survival::Surv()].
25+
#
26+
# `.time_as_binary_event()` takes a Surv object and converts it to a binary
27+
# outcome (if possible).
28+
2329
# @return
2430
# - `.extract_surv_status()` returns a vector.
2531
# - `.extract_surv_time()` returns a vector when the type is `"right"` or `"left"`
2632
# and a tibble otherwise.
33+
# - `.time_as_binary_event()` returns a two-level factor.
2734
# - Functions starting with `.is_` or `.check_` return logicals although the
2835
# latter will fail when `FALSE`.
2936

@@ -85,4 +92,24 @@
8592
res
8693
}
8794

95+
.time_as_binary_event <- function(surv, eval_time) {
96+
eval_time <- eval_time[!is.na(eval_time)]
97+
eval_time <- eval_time[eval_time >= 0 & is.finite(eval_time)]
98+
eval_time <- unique(eval_time)
99+
if (length(eval_time) != 1 || !is.numeric(eval_time)) {
100+
stop("'eval_time' should be a single, complete, finite numeric value.")
101+
}
102+
103+
event_time <- .extract_surv_time(surv)
104+
status <- .extract_surv_status(surv)
105+
is_event_before_t <- event_time <= eval_time & status == 1
106+
# Three possible contributions to the statistic from Graf 1999
107+
# Censoring time before eval_time, no contribution (Graf category 3)
108+
binary_res <- rep(NA_character_, length(event_time))
109+
# A real event prior to eval_time (Graf category 1)
110+
binary_res <- ifelse(is_event_before_t, "event", binary_res)
111+
# Observed time greater than eval_time (Graf category 2)
112+
binary_res <- ifelse(event_time > eval_time, "non-event", binary_res)
113+
factor(binary_res, levels = c("event", "non-event"))
114+
}
88115
# nocov end

R/survival-helpers.R

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# standalone-survival.R is loaded already. We'll capture the environment where
2+
# the functions of interest reside. We then document them and connect the
3+
# functions to their docs via the use of @alias. After the roxygen comments,
4+
# assign the function by referencing its name in the environment.
5+
6+
surv_ns <- environment(.extract_surv_status)
7+
8+
#' Extract survival time
9+
#'
10+
#' Extract the time component(s) from a [survival::Surv()] object.
11+
#' @name .extract_surv_time
12+
#' @aliases .extract_surv_time
13+
#' @param surv A single [survival::Surv()] object.
14+
#' @return A vector when the type is `"right"` or `"left"` and a tibble otherwise.
15+
#' @export
16+
assign(".extract_surv_time", surv_ns[[".extract_surv_time"]])
17+
18+
#' Extract survival status
19+
#'
20+
#' Extract the status from a [survival::Surv()] object.
21+
#' @name .extract_surv_status
22+
#' @aliases .extract_surv_status
23+
#' @param surv A single [survival::Surv()] object.
24+
#' @return A numeric vector.
25+
#' @export
26+
assign(".extract_surv_status", surv_ns[[".extract_surv_status"]])
27+
28+
#' Convert survival objects to binary factors
29+
#'
30+
#' For a given evaluation time, convert a [survival::Surv()] object to a binary
31+
#' factor with levels `"event"` and `"non-event"`.
32+
#'
33+
#' @name .time_as_binary_event
34+
#' @param surv A single [survival::Surv()] object.
35+
#' @param eval_time A single numeric value for the evaluation time.
36+
#' @return A two level factor.
37+
#' @details
38+
#' The following three cases can occur:
39+
#' - **Events**: Evaluation time is greater than or equal to the event time
40+
#' ("it has already happened").
41+
#' - **Non-events**: Evaluation time is less than the observed time, censored
42+
#' or not ("nothing has happened yet").
43+
#' - **Ambiguous outcomes**: Evaluation time is greater than or equal to the
44+
#' observed censored time ("we don't know if anything might have happened by now").
45+
#' A missing value is returned for these observations.
46+
#'
47+
#' @references Graf, E., Schmoor, C., Sauerbrei, W., and Schumacher, M. (1999).
48+
#' "Assessment and Comparison of Prognostic Classification Schemes for Survival Data."
49+
#' _Statistics in Medicine_, 18, 2529-2545.
50+
#' @export
51+
assign(".time_as_binary_event", surv_ns[[".time_as_binary_event"]])

_pkgdown.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,7 @@ reference:
104104
- required_pkgs
105105
- required_pkgs.model_spec
106106
- req_pkgs
107+
- .extract_surv_status
108+
- .extract_surv_time
107109
- .model_param_name_key
110+
- .time_as_binary_event

man/dot-extract_surv_status.Rd

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/dot-extract_surv_time.Rd

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/dot-time_as_binary_event.Rd

Lines changed: 34 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)