# How to simulate censored data

I'm wondering how can I simulate a sample of n Weibull distribution lifetimes that include Type I right-censored observations. For instance lets have the n = 3, shape = 3, scale = 1 and the censoring rate = .15, and the censoring time = .88. I know how to generate a Weibull sample but I do not know how to generate a censored data that have type I right-censored in R.

T = rweibull(3, shape=.5, scale=1)


(As a matter of R coding style, it is best not to use T as a variable name, because it is an alias for TRUE, and that practice will inevitably lead to problems.)

Your question is somewhat ambiguous; there are several ways to interpret it. Let's walk through them:

1. You stipulate that you want to simulate type 1 censoring. That is typically taken to mean that the experiment is run for a period of time, and that whichever study units have not had the event by then are censored. If that is what you meant, then it is not (necessarily) possible to stipulate the shape and scale parameters, and the censoring time and rate simultaneously. Having stipulated any three, the last is necessarily fixed.

(Attempting to) solve for the shape parameter:
This fails; it seems that it is impossible to have a 15% censoring rate at a censoring time of .88 with a Weibull distribution where the scale parameter is held at 1, no matter what the shape parameter is.

optim(.5, fn=function(shp){(pweibull(.88, shape=shp, scale=1, lower.tail=F)-.15)^2})
# $par # [1] 4.768372e-08 # ... # There were 46 warnings (use warnings() to see them) pweibull(.88, shape=4.768372e-08, scale=1, lower.tail=F) # [1] 0.3678794 optim(.5, fn=function(shp){(pweibull(.88, shape=shp, scale=1, lower.tail=F)-.15)^2}, control=list(reltol=1e-16)) #$par
# [1] 9.769963e-16
# ...
# There were 50 or more warnings (use warnings() to see the first 50)
pweibull(.88, shape=9.769963e-16, scale=1, lower.tail=F)
# [1] 0.3678794


Solving for the scale parameter:

optim(1, fn=function(scl){(pweibull(.88, shape=.5, scale=scl, lower.tail=F)-.15)^2})
# \$par
# [1] 0.2445312
# ...
pweibull(.88, shape=.5, scale=0.2445312, lower.tail=F)
# [1] 0.1500135


Solving for the censoring time:

qweibull(.15, shape=.5, scale=1, lower.tail=F)
# [1] 3.599064


Solving for the censoring rate:

pweibull(.88, shape=.5, scale=1, lower.tail=F)
# [1] 0.3913773

2. On the other hand, we can think of censoring as randomly (and typically independently) occurring throughout the study due to, say, dropout. In that case, the procedure is to simulate two sets of Weibull variates. Then you simply note which came first: you use the lesser value as the endpoint and call that unit censored if the lesser value was the censoring time. For example:

set.seed(0775)
t    = rweibull(3, shape=.5, scale=1)
t      # [1] 0.7433678 1.1325749 0.2784812
c    = rweibull(3, shape=.5, scale=1.5)
c      # [1] 3.3242417 2.8866217 0.9779436
time = pmin(t, c)
time   # [1] 0.7433678 1.1325749 0.2784812
cens = ifelse(c<t, 1, 0)
cens   # [1] 0 0 0

• very interesting answer (the optim function is awesome), but how would you calibrate your second answer to achieve a certain percentage of censoring? Feb 28, 2020 at 18:12
• @DanChaltiel, the 2nd one isn't really calibrated--it's just random. It also may not be possible to achieve a desired proportion, given other aspects you want (analogous to #1). That said, it may be possible to identify a population proportion (the observed proportion will bounce around from iteration to iteration) by optimizing the censored distribution relative to the event distribution. Feb 28, 2020 at 18:17

Just to be sure we're talking about the same thing, type-I censoring is when

... an experiment has a set number of subjects or items and stops the experiment at a predetermined time, at which point any subjects remaining are right-censored.

To generate right censored data using censoring time = 0.88, you'd just use the min function:

T <- rweibull(3, shape=.5, scale=1)
censoring_time <- 0.88
T_censored <- min(censoring_time, T)


However, I'm not entirely sure what you mean when you say, "censoring rate = 0.15"... Do you mean to say that 15% of your subjects are right censored? These notes on censorship seem to indicate that the only parameter one needs for Type-I censorship is censoring time, so I'm not sure how this rate factors in.

• Note that your quotation is not a definition of censoring: it is only an example. Right censoring occurs when each value is compared to a predetermined threshold and replaced by a non-numerical censoring indicator when the value exceeds that threshold. Regardless, applying min (or, more generally, pmin) is the way to simulate it in R. (An example of right censoring in a non-survival study is the analysis of bacterial colonies in wastewater. It is done by manually counting those visible on a microscope slide. With heavy contamination, the result is given as "too numerous to count.")
– whuber
Jul 19, 2015 at 18:12
• Using pmin() indeeds makes a lot more sense than using min() here. Apr 6, 2021 at 23:37