Come creare i dati di sopravvivenza di un giocattolo (tempo dell'evento) con la corretta censura


12

Vorrei creare un giocattolo di sopravvivenza (tempo all'evento) che sia correttamente censurato e segua una certa distribuzione con pericoli proporzionali e pericoli costanti di base.

Ho creato i dati come segue, ma non sono in grado di ottenere rapporti di rischio stimati vicini ai valori reali dopo aver adattato un modello di rischi proporzionali di Cox ai dati simulati.

Cos'ho fatto di sbagliato?

Codici R:

library(survival)

#set parameters
set.seed(1234)

n = 40000 #sample size


#functional relationship

lambda=0.000020 #constant baseline hazard 2 per 100000 per 1 unit time

b_haz <-function(t) #baseline hazard
  {
    lambda #constant hazard wrt time 
  }

x = cbind(hba1c=rnorm(n,2,.5)-2,age=rnorm(n,40,5)-40,duration=rnorm(n,10,2)-10)

B = c(1.1,1.2,1.3) # hazard ratios (model coefficients)

hist(x %*% B) #distribution of scores

haz <-function(t) #hazard function
{
  b_haz(t) * exp(x %*% B)
}

c_hf <-function(t) #cumulative hazards function
{
  exp(x %*% B) * lambda * t 
}

S <- function(t) #survival function
{
  exp(-c_hf(t))
}

S(.005)
S(1)
S(5)

#simulate censoring

time = rnorm(n,10,2)

S_prob = S(time)

#simulate events

event = ifelse(runif(1)>S_prob,1,0)

#model fit

km = survfit(Surv(time,event)~1,data=data.frame(x))

plot(km) #kaplan-meier plot

#Cox PH model

fit = coxph(Surv(time,event)~ hba1c+age+duration, data=data.frame(x))

summary(fit)            

cox.zph(fit)

risultati:

Call:
coxph(formula = Surv(time, event) ~ hba1c + age + duration, data = data.frame(x))

  n= 40000, number of events= 3043 

             coef exp(coef) se(coef)     z Pr(>|z|)    
hba1c    0.236479  1.266780 0.035612  6.64 3.13e-11 ***
age      0.351304  1.420919 0.003792 92.63  < 2e-16 ***
duration 0.356629  1.428506 0.008952 39.84  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

         exp(coef) exp(-coef) lower .95 upper .95
hba1c        1.267     0.7894     1.181     1.358
age          1.421     0.7038     1.410     1.432
duration     1.429     0.7000     1.404     1.454

Concordance= 0.964  (se = 0.006 )
Rsquare= 0.239   (max possible= 0.767 )
Likelihood ratio test= 10926  on 3 df,   p=0
Wald test            = 10568  on 3 df,   p=0
Score (logrank) test = 11041  on 3 df,   p=0

ma i valori veri sono impostati come

B = c(1.1,1.2,1.3) # hazard ratios (model coefficients)

1
per il tuo compito, un rapido avvio è utilizzare un pacchetto di simulazione esistente: cran.r-project.org/web/packages/survsim/index.html
zhanxw,

Risposte:


19

Non mi è chiaro come si generano i tempi degli eventi (che, nel tuo caso, potrebbero essere ) e gli indicatori degli eventi:<0

time = rnorm(n,10,2) 
S_prob = S(time)
event = ifelse(runif(1)>S_prob,1,0)

Quindi ecco un metodo generico, seguito da un codice R.


Generazione di tempi di sopravvivenza per simulare modelli di rischi proporzionali di Cox

Per generare tempi di eventi dal modello di rischi proporzionali, possiamo usare il metodo della probabilità inversa (Bender et al., 2005) : se è uniforme su e se è la funzione di sopravvivenza condizionale derivata dal modello di rischi proporzionali, ovvero quindi è un dato di fatto che la variabile casuale ha la funzione di sopravvivenza( 0 , 1 ) S ( V(0,1)S ( tS(|x)

S(t|x)=exp(H0(t)exp(xβ)()
T=S1(V|x)=H01(log(V)exp(xβ))
S(|x). Questo risultato è noto come `` trasformazione integrale di probabilità inversa ''. Pertanto, per generare un tempo di sopravvivenza dato il vettore covariata, è sufficiente disegnare da e per effettuare la trasformazione inversa .TS(|x)vVU(0,1)t=S1(v|x)

Esempio [rischio basale Weibull]

Sia con forma e scala . Quindi e . Seguendo il metodo della probabilità inversa, si ottiene una realizzazione di calcolando con una variazione uniforme su . Utilizzando i risultati sulle trasformazioni di variabili casuali, si può notare che ha una distribuzione Weibull condizionale (datoh0(t)=λρtρ1ρ>0λ>0H0(t)=λtρH01(t)=(tλ)1ρt = ( - log ( v )TS(|x) v(0,1)Txρλexp(xβ)

t=(log(v)λexp(xβ))1ρ
v(0,1)Tx) con forma e scala .ρλexp(xβ)

Codice R.

La seguente funzione R genera un set di dati con una singola covariata binaria (ad es. Un indicatore di trattamento). Il pericolo di base ha una forma di Weibull. I tempi di censura sono estratti casualmente da una distribuzione esponenziale.x

# baseline hazard: Weibull

# N = sample size    
# lambda = scale parameter in h0()
# rho = shape parameter in h0()
# beta = fixed effect parameter
# rateC = rate parameter of the exponential distribution of C

simulWeib <- function(N, lambda, rho, beta, rateC)
{
  # covariate --> N Bernoulli trials
  x <- sample(x=c(0, 1), size=N, replace=TRUE, prob=c(0.5, 0.5))

  # Weibull latent event times
  v <- runif(n=N)
  Tlat <- (- log(v) / (lambda * exp(x * beta)))^(1 / rho)

  # censoring times
  C <- rexp(n=N, rate=rateC)

  # follow-up times and event indicators
  time <- pmin(Tlat, C)
  status <- as.numeric(Tlat <= C)

  # data set
  data.frame(id=1:N,
             time=time,
             status=status,
             x=x)
}

Test

Ecco una rapida simulazione con :β=0.6

set.seed(1234)
betaHat <- rep(NA, 1e3)
for(k in 1:1e3)
{
  dat <- simulWeib(N=100, lambda=0.01, rho=1, beta=-0.6, rateC=0.001)
  fit <- coxph(Surv(time, status) ~ x, data=dat)
  betaHat[k] <- fit$coef
}

> mean(betaHat)
[1] -0.6085473

Grazie per la tua eccellente risposta. Mi sono reso conto di aver incasinato i tempi degli eventi ottenendo lo stato degli eventi dopo aver randomizzato gli orari degli eventi, il che non aveva senso ... sciocco me!
stats_newb,

Posso chiederti: c'è qualche motivo specifico per cui trai tempo di censura da una distribuzione esponenziale?
pthao,

@pthao: non c'è un motivo particolare (questa era solo un'illustrazione in cui ho usato la distribuzione esponenziale)
ocram

1
Esistono linee guida per la scelta della distribuzione per i tempi di censura?
pthao,

@ocram È interessante notare che quando eseguo flexsurvreg(Surv(time, status) ~ x, data=dat, dist = "weibull")gli stessi dati simulati, il coefficiente appare come 0.6212. Perchè è questo?
Né il

3

Per la distribuzione di Weibull,
S (t) =e(λe(xβ)t)ρ

" " sarà solo per il registro (v)(1/rho)

così, ho modificato in questo modo

Tlat <- (- log(v))^(1 / rho) / (lambda * exp(x * beta))

se rho = 1, il risultato sarà lo stesso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.