Complex censoring with rcenscomp

The rcenscomp family separates latent event times from the observation operator. Every specialized function returns the observed table in data, optional exact quantities in latent, and design-specific diagnostics.

A latent sample

The Weibull helpers use shape alpha and rate-like beta.

library(rcens)
set.seed(2026)
x <- rcenscomp_rweibull_rate(20, beta = 2.5, alpha = 1.5)
head(x)
#> [1] 0.2740043 0.3801791 0.8517231 0.6308779 0.3810821 1.2948675

Interval censoring

A common visit schedule replaces each exact event by a left, interval, or right-censored record.

interval_dat <- rcenscomp_interval(x, visits = c(0.2, 0.4, 0.8))
head(as.data.frame(interval_dat))
#>   id   L   R   status
#> 1  1 0.2 0.4 interval
#> 2  2 0.2 0.4 interval
#> 3  3 0.8 Inf    right
#> 4  4 0.4 0.8 interval
#> 5  5 0.2 0.4 interval
#> 6  6 0.8 Inf    right
interval_dat$diagnostics[c("n_left", "n_interval", "n_right")]
#> $n_left
#> [1] 2
#> 
#> $n_interval
#> [1] 12
#> 
#> $n_right
#> [1] 6

Current status

Current-status data record whether an event occurred by one inspection time; the inspection is not an exact event time.

inspection <- seq(0.1, 1, length.out = length(x))
current_dat <- rcenscomp_current_status(x, inspection)
head(as.data.frame(current_dat))
#>   id inspection status
#> 1  1  0.1000000      0
#> 2  2  0.1473684      0
#> 3  3  0.1947368      0
#> 4  4  0.2421053      0
#> 5  5  0.2894737      0
#> 6  6  0.3368421      0

Hybrid Type-I and Type-II

The two schemes differ only in whether the stopping time is the minimum or maximum of T and the target order statistic.

hybrid_i <- rcenscomp_hybrid_type1(x, T = 0.6, r = 10)
hybrid_ii <- rcenscomp_hybrid_type2(x, T = 0.6, r = 10)
c(Type_I = hybrid_i$design$Tstar, Type_II = hybrid_ii$design$Tstar)
#>    Type_I   Type_II 
#> 0.5538861 0.6000000
c(Type_I = hybrid_i$design$D, Type_II = hybrid_ii$design$D)
#>  Type_I Type_II 
#>      10      11

Progressive Type-II

Withdrawal selection is uniform among eligible survivors. A valid plan has sum(R) = n - length(R).

set.seed(2027)
R <- rep(1L, 10)
prog_ii <- rcenscomp_progressive_type2(x, R)
prog_ii$design$compact
#>    failure_order failure_id failure_time R_used
#> 1              1          8    0.1530223      1
#> 2              2         14    0.1628189      1
#> 3              3          1    0.2740043      1
#> 4              4         12    0.2789699      1
#> 5              5         10    0.3614820      1
#> 6              6          2    0.3801791      1
#> 7              7          5    0.3810821      1
#> 8              8         17    0.3890203      1
#> 9              9          4    0.6308779      1
#> 10            10          3    0.8517231      1

Progressive hybrid

The time cap can stop a progressive plan before its target failure count.

set.seed(2028)
prog_hybrid <- rcenscomp_progressive_hybrid(x, R, T = 0.5)
prog_hybrid$diagnostics[c("D", "Rstar", "stopping_time")]
#> $D
#> [1] 7
#> 
#> $Rstar
#> [1] 6
#> 
#> $stopping_time
#> [1] 0.5

Delayed entry

Units that fail before entry are absent because of truncation. They are not censored observations.

entry <- seq(0, 0.3, length.out = length(x))
delayed <- rcenscomp_delayed_entry(x, entry, censor = rep(1.5, length(x)))
head(as.data.frame(delayed))
#>   id      entry      time delta
#> 1  1 0.00000000 0.2740043     1
#> 2  2 0.01578947 0.3801791     1
#> 3  3 0.03157895 0.8517231     1
#> 4  4 0.04736842 0.6308779     1
#> 5  5 0.06315789 0.3810821     1
#> 6  6 0.07894737 1.2948675     1
delayed$diagnostics[c("n_truncated", "n_observed", "n_events")]
#> $n_truncated
#> [1] 1
#> 
#> $n_observed
#> [1] 19
#> 
#> $n_events
#> [1] 17

Informative censoring through shared frailty

This generator shares an unobserved individual frailty between the event and censoring processes. It is a sensitivity mechanism, not an inferential correction.

set.seed(2029)
informative <- rcenscomp_informative_frailty(
  n = 20,
  beta_x = 2.5, alpha_x = 1.5,
  beta_c = 1.3, alpha_c = 1.1,
  gamma_x = c(0.5, -0.3), gamma_c = c(-0.2, 0.4),
  theta = 0.6, rho = 0.8
)
head(as.data.frame(informative))
#>   id       time delta z1         z2
#> 1  1 0.08032188     1  0 -0.5482899
#> 2  2 0.43827874     0  1 -0.4914751
#> 3  3 0.29676430     0  0  0.1092568
#> 4  4 0.35067242     1  1 -2.8233854
#> 5  5 0.09079266     0  0 -0.8948013
#> 6  6 0.25175357     1  1  0.3652177

Competing risks

Status zero is censoring; positive integers identify the observed cause. The independence of latent cause times is a simulation assumption.

set.seed(2030)
competing <- rcenscomp_competing_risks(
  n = 20,
  beta = c(1.2, 0.8),
  alpha = c(1.4, 1.1),
  censor_time = 1
)
table(as.data.frame(competing)$status)
#> 
#>  0  1  2 
#>  3 11  6

Interpreting the observed objects

The observed columns determine the appropriate likelihood representation:

Keeping latent is useful for auditing simulation code. Setting keep_latent = FALSE removes those unobserved values from the returned object.