So erstellen Sie mit der richtigen Zensur Daten zum Spielzeugüberleben (Time-to-Event)


12

Ich möchte Daten zum Spielzeugüberleben (Zeit bis zum Ereignis) erstellen, die richtig zensiert sind und einer gewissen Verteilung mit proportionalen Gefahren und einer konstanten Grundliniengefahr folgen.

Ich habe die Daten wie folgt erstellt, kann jedoch keine geschätzten Gefährdungsquoten erhalten, die nahe an den tatsächlichen Werten liegen, nachdem ein Cox-Proportional-Gefährdungsmodell an die simulierten Daten angepasst wurde.

Was habe ich falsch gemacht?

R-Codes:

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)

Ergebnisse:

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

aber wahre Werte werden als gesetzt

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

1
Für Ihre Aufgabe besteht ein schneller Start darin, ein vorhandenes Simulationspaket zu verwenden: cran.r-project.org/web/packages/survsim/index.html
zhanxw

Antworten:


19

Mir ist nicht klar, wie Sie Ihre Ereigniszeiten (die in Ihrem Fall könnten ) und Ereignisindikatoren generieren :<0

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

Hier ist also eine generische Methode, gefolgt von etwas R-Code.


Generieren von Überlebenszeiten zur Simulation von Cox-Proportional-Hazard-Modellen

V(0,1)S(|x)

S(t|x)=exp(H0(t)exp(xβ)()
T=S1(V|x)=H01(log(V)exp(xβ))
S(|x)TS(|x)vVU(0,1)t=S1(v|x)

Beispiel [Weibull-Grundliniengefahr]

h0(t)=λρtρ1ρ>0λ>0H0(t)=λtρH01(t)=(tλ)1ρTS(|x)

t=(log(v)λexp(xβ))1ρ
v(0,1)Txρλexp(xβ)

R-Code

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)
}

Prüfung

β=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

Vielen Dank für Ihre hervorragende Antwort. Mir wurde klar, dass ich die Ereigniszeiten durcheinander gebracht hatte, indem ich den Ereignisstatus erhielt, nachdem ich die Ereigniszeiten randomisiert hatte, was keinen Sinn ergab. Dumm mich!
stats_newb

Darf ich fragen, ob es einen bestimmten Grund gibt, warum Sie die Zensurzeit aus einer Exponentialverteilung ziehen?
Pthao

@pthao: Es gibt keinen besonderen Grund (dies war nur eine Illustration, wo ich die Exponentialverteilung verwendet habe)
ocram

1
Gibt es eine Richtlinie für die Auswahl der Verteilung für die Zensurzeiten?
Pthao

@ocram Interessanterweise flexsurvreg(Surv(time, status) ~ x, data=dat, dist = "weibull")erscheint der Koeffizient , wenn ich mit denselben simulierten Daten laufe 0.6212. Warum ist das?
Weder-noch

3

Für die Weibull-Verteilung gilt
S (t) =e- -(λe(xβ)t)ρ

""(1/.rhÖ)"wird nur für log (v) sein

Also habe ich so modifiziert

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

Wenn rho = 1 ist, ist das Ergebnis dasselbe.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.