2424# ' @section Plot Descriptions:
2525# ' \describe{
2626# ' \item{`ppc_km_overlay()`}{
27- # ' Empirical CCDF estimates of each dataset (row) in `yrep` are overlaid,
28- # ' with the Kaplan-Meier estimate (Kaplan and Meier, 1958) for `y` itself on
29- # ' top (and in a darker shade). This is a PPC suitable for right-censored
30- # ' `y`. Note that the replicated data from `yrep` is assumed to be
31- # ' uncensored.
27+ # ' Empirical CCDF estimates of each dataset (row) in `yrep` are overlaid, with
28+ # ' the Kaplan-Meier estimate (Kaplan and Meier, 1958) for `y` itself on top
29+ # ' (and in a darker shade). This is a PPC suitable for right-censored `y`.
30+ # ' Note that the replicated data from `yrep` is assumed to be uncensored. Left
31+ # ' truncation (delayed entry) times for `y` can be specified using
32+ # ' `left_truncation_y`.
3233# ' }
3334# ' \item{`ppc_km_overlay_grouped()`}{
3435# ' The same as `ppc_km_overlay()`, but with separate facets by `group`.
4041# ' @template reference-km
4142# '
4243# ' @examples
44+ # ' \donttest{
4345# ' color_scheme_set("brightblue")
44- # ' y <- example_y_data()
46+ # '
4547# ' # For illustrative purposes, (right-)censor values y > 110:
48+ # ' y <- example_y_data()
4649# ' status_y <- as.numeric(y <= 110)
4750# ' y <- pmin(y, 110)
51+ # '
4852# ' # In reality, the replicated data (yrep) would be obtained from a
4953# ' # model which takes the censoring of y properly into account. Here,
5054# ' # for illustrative purposes, we simply use example_yrep_draws():
5155# ' yrep <- example_yrep_draws()
5256# ' dim(yrep)
53- # ' \donttest{
57+ # '
58+ # ' # Overlay 25 curves
5459# ' ppc_km_overlay(y, yrep[1:25, ], status_y = status_y)
55- # ' }
60+ # '
61+ # ' # With extrapolation_factor = 1 (no extrapolation)
62+ # ' ppc_km_overlay(y, yrep[1:25, ], status_y = status_y, extrapolation_factor = 1)
63+ # '
64+ # ' # With extrapolation_factor = Inf (show all posterior predictive draws)
65+ # ' ppc_km_overlay(y, yrep[1:25, ], status_y = status_y, extrapolation_factor = Inf)
66+ # '
5667# ' # With separate facets by group:
5768# ' group <- example_group_data()
58- # ' \donttest{
5969# ' ppc_km_overlay_grouped(y, yrep[1:25, ], group = group, status_y = status_y)
70+ # '
71+ # ' # With left-truncation (delayed entry) times:
72+ # ' min_vals <- pmin(y, apply(yrep, 2, min))
73+ # ' left_truncation_y <- rep(0, length(y))
74+ # ' condition <- y > mean(y) / 2
75+ # ' left_truncation_y[condition] <- pmin(
76+ # ' runif(sum(condition), min = 0.6, max = 0.99) * y[condition],
77+ # ' min_vals[condition] - 0.001
78+ # ' )
79+ # ' ppc_km_overlay(y, yrep[1:25, ], status_y = status_y,
80+ # ' left_truncation_y = left_truncation_y)
6081# ' }
6182NULL
6283
6586# ' @param status_y The status indicator for the observations from `y`. This must
6687# ' be a numeric vector of the same length as `y` with values in \{0, 1\} (0 =
6788# ' right censored, 1 = event).
89+ # ' @param left_truncation_y Optional parameter that specifies left-truncation
90+ # ' (delayed entry) times for the observations from `y`. This must be a numeric
91+ # ' vector of the same length as `y`. If `NULL` (default), no left-truncation
92+ # ' is assumed.
93+ # ' @param extrapolation_factor A numeric value (>=1) that controls how far the
94+ # ' plot is extended beyond the largest observed value in `y`. The default
95+ # ' value is 1.2, which corresponds to 20 % extrapolation. Note that all
96+ # ' posterior predictive draws may not be shown by default because of the
97+ # ' controlled extrapolation. To display all posterior predictive draws, set
98+ # ' `extrapolation_factor = Inf`.
99+ # '
68100ppc_km_overlay <- function (
69101 y ,
70102 yrep ,
71103 ... ,
72104 status_y ,
105+ left_truncation_y = NULL ,
106+ extrapolation_factor = 1.2 ,
73107 size = 0.25 ,
74108 alpha = 0.7
75109) {
@@ -79,8 +113,25 @@ ppc_km_overlay <- function(
79113 suggested_package(" survival" )
80114 suggested_package(" ggfortify" )
81115
82- stopifnot(is.numeric(status_y ))
83- stopifnot(all(status_y %in% c(0 , 1 )))
116+ if (! is.numeric(status_y ) || length(status_y ) != length(y ) || ! all(status_y %in% c(0 , 1 ))) {
117+ stop(" `status_y` must be a numeric vector of 0s and 1s the same length as `y`." , call. = FALSE )
118+ }
119+
120+ if (! is.null(left_truncation_y )) {
121+ if (! is.numeric(left_truncation_y ) || length(left_truncation_y ) != length(y )) {
122+ stop(" `left_truncation_y` must be a numeric vector of the same length as `y`." , call. = FALSE )
123+ }
124+ }
125+
126+ if (extrapolation_factor < 1 ) {
127+ stop(" `extrapolation_factor` must be greater than or equal to 1." , call. = FALSE )
128+ }
129+ if (extrapolation_factor == 1.2 ) {
130+ message(
131+ " Note: `extrapolation_factor` now defaults to 1.2 (20%).\n " ,
132+ " To display all posterior predictive draws, set `extrapolation_factor = Inf`."
133+ )
134+ }
84135
85136 data <- ppc_data(y , yrep , group = status_y )
86137
@@ -96,7 +147,12 @@ ppc_km_overlay <- function(
96147 as.numeric(as.character(.data $ group )),
97148 1 ))
98149
99- sf_form <- survival :: Surv(value , group ) ~ rep_label
150+ if (is.null(left_truncation_y )) {
151+ sf_form <- survival :: Surv(time = data $ value , event = data $ group ) ~ rep_label
152+ } else {
153+ sf_form <- survival :: Surv(time = left_truncation_y [data $ y_id ], time2 = data $ value , event = data $ group ) ~ rep_label
154+ }
155+
100156 if (! is.null(add_group )) {
101157 data <- dplyr :: inner_join(data ,
102158 tibble :: tibble(y_id = seq_along(y ),
@@ -120,6 +176,10 @@ ppc_km_overlay <- function(
120176 fsf $ is_y_size <- ifelse(fsf $ is_y_color == " yrep" , size , 1 )
121177 fsf $ is_y_alpha <- ifelse(fsf $ is_y_color == " yrep" , alpha , 1 )
122178
179+ max_time_y <- max(y , na.rm = TRUE )
180+ fsf <- fsf %> %
181+ dplyr :: filter(.data $ is_y_color != " yrep" | .data $ time < = max_time_y * extrapolation_factor )
182+
123183 # Ensure that the observed data gets plotted last by reordering the
124184 # levels of the factor "strata"
125185 fsf $ strata <- factor (fsf $ strata , levels = rev(levels(fsf $ strata )))
@@ -164,6 +224,8 @@ ppc_km_overlay_grouped <- function(
164224 group ,
165225 ... ,
166226 status_y ,
227+ left_truncation_y = NULL ,
228+ extrapolation_factor = 1.2 ,
167229 size = 0.25 ,
168230 alpha = 0.7
169231) {
@@ -175,8 +237,10 @@ ppc_km_overlay_grouped <- function(
175237 add_group = group ,
176238 ... ,
177239 status_y = status_y ,
240+ left_truncation_y = left_truncation_y ,
178241 size = size ,
179- alpha = alpha
242+ alpha = alpha ,
243+ extrapolation_factor = extrapolation_factor
180244 )
181245
182246 p_overlay +
0 commit comments