#Preliminares
#install.packages("survival")
#install.packages("KMsurv")
#install.packages("survMisc")
#install.packages("survminer")
#install.packages("flexsurv")
#install.packages("actuar")
#install.packages("dplyr")
#install.packages("moments")
#install.packages("rms")
#install.packages("SurvRegCensCov")
library(survival) #Kaplan-Meier con la función survfit()
library(KMsurv)
library(survMisc)
library(survminer) #graficar curva de supervivencia estimada con ggsurvplot()
library(ggfortify)
library(flexsurv) #estimar función de supervivencia con distribuciones paramétricas con la función flexsurvreg()
library(actuar)
library(dplyr)
library(readr)
library(moments)
library(car)
library("SurvRegCensCov")
La duración de una huelga;
el tiempo que una persona permanece en el desempleo;
el periodo de tiempo que hay entre que una mujer tiene pareja hasta que nace su primer hijo o entre sus sucesivas maternidades;
el tiempo que transcurre entre las sucesivas compras de bienes duraderos,
Un suceso es el resultado de cualquier acontecimiento que ocurre en la vida de cualquier individuo o empresa.
Ej. Situación laboral de un individuo; situación financiera de una empresa.
Sinónimos: evento o acontecimiento
La medida del tiempo que transcurre entre su inicio y su final.
aquella situación descrita por una o varias fundamentales que son permanentes a lo largo del tiempo.
cuando esta o estas característicasfundamentales definidoras del estado se alteran. A medida que el periodo transcurre, siempre, en cada momento, existe un riesgo de que se produzca un tránsito. Hay una dualidad entre duración y tránsito
Consideremos una población de individuos. De uno de ellos observamos el tiempo hasta el tránsito (failure) o hasta la pérdida (censura).
\(f(t)\) es la función de densidad de probabilidad (fdp) de la variable \(T\) en el tiempo \(t\). Puede ser continua o discreta.
Su función de distribución acumulada \(F(t)\) es $ P(Tt)=_0^t f(s)ds$
\[S(t)=P(T>t)=1-F(t)\] Es la probabilidad de que la longitud de un periodo sea al menos \(t\).
Es la probabilidad de que el periodo finalice,i.e, que haya un tránsito, en el intervalo \(t +\Delta t\), condicional a que la longitud del periodo sea al menos \(t\). En otras palabras, la tasa de riesgo es la probabilidad de que algo ocurra después de la duración \(t\), condicionada a que al menos su duración sea \(t\).
\[h(t)=\lim_{\bigtriangleup t \to 0} \frac {P( t\leq T \leq t+\bigtriangleup t|T \geq t)}{\bigtriangleup t}=\lim_{\bigtriangleup t \to 0} \frac {F(t+\bigtriangleup t )-F(t)}{\bigtriangleup tS(t)}=\dfrac{f(t)}{S(t)}\]
\[\lambda(t)=\frac{f(t)}{S(t)}\] Probabilidad instantánea de dejar un estado, condicional a sobrevivir al tiempo \(t\).
La función de riesgo recoge los valores de la tasa de riesgo para cualquier valor de \(t\)
Los modelos de duración se caracterizan por el modo en que especifican la tasa de riesgo.
\[\Lambda(t)=\int_0^t\lambda(s)ds=-\ln S(t)\] ### Enfoques para estimar los modelos de duración
Ajuste del modelo Básicamente, existen tres enfoques para ajustar los modelos de supervivencia:
-Un segundo enfoque es lo que podría llamarse una estrategia flexible o semiparamétrica , en la que hacemos suposiciones leves sobre el peligro de referencia.\(\lambda_0(t)\). Específicamente, podemos subdividir el tiempo en intervalos razonablemente pequeños y asumir que el riesgo de línea de base es constante en cada intervalo, lo que conduce a un modelo exponencial por partes.
-El tercer enfoque es una estrategia no paramétrica que se centra en la estimación de los coeficientes de regresión \(\beta\) dejando la baseline Hazard \(\lambda_0(t)\) completamente sin especificar. Este enfoque se basa en una función de verosimilitud parcial propuesta por Cox (1972) en su artículo original.
Se sugiere estudiar el tema en el siguiente libro.
(Example 19.8 Survival Models for Strike Duration)
Ejemplo tomado de la sección 19.4, Green pág 862: MODELS FOR DURATION.
Se tienen registros de las duraciones, en días, de 62 huelgas que comenzaron en junio de los años 1968 a 1976. Cada una involucró al menos a 1,000 trabajadores y comenzó al vencimiento o reapertura de un contrato. Kennan informó la duración real. En su encuesta, Kiefer (1985), utilizando las mismas observaciones, censuró los datos a los 80 días para demostrar los efectos de la censura. Descarga los datos aquí.
<-read_csv("./TableF19-2.csv")
strikesattach(strikes)
summary(strikes)
## T PROD
## Min. : 1.00 Min. :-0.10443
## 1st Qu.: 10.25 1st Qu.:-0.03143
## Median : 27.00 Median : 0.01138
## Mean : 42.68 Mean : 0.01102
## 3rd Qu.: 51.25 3rd Qu.: 0.06450
## Max. :216.00 Max. : 0.07427
#View(strikes)
head(strikes)
## # A tibble: 6 x 2
## T PROD
## <dbl> <dbl>
## 1 7 0.0114
## 2 9 0.0114
## 3 13 0.0114
## 4 14 0.0114
## 5 26 0.0114
## 6 29 0.0114
La variable PROD es el residuo de una regresión lineal del logaritmo de la producción industrial en el tiempo, el tiempo al cuadrado y un conjunto de variables ficticias mensuales. Mide la producción industrial agregada menos los componentes tendenciales y estacionales.
Para estos datos necesitamos una variable de censura para indicar si un proceso aún está en curso. Abajo creamos la variable de censura, STATUS, para todas las duraciones por debajo de 80 días.
$status<-strikes$T<80
strikesdetach(strikes)
attach(strikes)
#Creación de un objeto Surv: la combinación de información entre los tiempos y su censura.
Surv(strikes$T,strikes$status)
## [1] 7 9 13 14 26 29 52 130+ 9 37 41 49 52 119+ 3
## [16] 17 19 28 72 99+ 104+ 114+ 152+ 153+ 216+ 15 61 98+ 2 25
## [31] 85+ 3 10 1 2 3 3 3 4 8 11 22 23 27 32
## [46] 33 35 43 43 44 100+ 5 49 2 12 12 21 21 27 38
## [61] 42 117+
#Surv(Time,Event), toma como argumentos: Time como el tiempo hasta la observación y Event un indicador en donde es 1 si se observó el evento y 0 si es censura.
Los tiempos censurados se caracterizan por tener el símbolo + acompañado a su derecha.
Censura. Si disponemos de una muestra de observaciones de la duración de \(N\) sucesos, la censura ocurre cuando al medir la duración de algún suceso, éste todavía permanece en el estado inicial, sin haber transitado hasta otro estado. El resultado en este caso nos dice que el fenómeno ha durado al menos la medida tomada, sin ninguna información sobre la duración real del fenómeno hasta la transición. Tránsito que ocurrirá, con seguridad, un tiempo después de nuestra medida. Así, la censura es, en general, no informativa sobre la duración de un suceso.
Función de supervivencia (survival function): es la probabilidad de que la longitud de un periodo sea al menos \(t\).
# Guardando el Objeto Surv
<- Surv(strikes$T,strikes$status) #Creando objeto tipo Surv
strikes.surv<- survfit(strikes.surv~1, data =strikes, type = "kaplan-meier") #Estimación Kaplan Meier
strikes.km
# Sin Guardar el Objeto Surv
#strikes.km <- survfit(Surv(T,status)~1, data =strikes, type = "kaplan-meier")
La estimación de la función de supervivencia se lleva a cabo con la función summary().
summary(strikes.km) #Resumen estadístico
## Call: survfit(formula = strikes.surv ~ 1, data = strikes, type = "kaplan-meier")
##
## time n.risk n.event survival std.err lower 95% CI upper 95% CI
## 1 62 1 0.984 0.0160 0.953 1.000
## 2 61 3 0.935 0.0312 0.876 0.999
## 3 58 5 0.855 0.0447 0.772 0.947
## 4 53 1 0.839 0.0467 0.752 0.935
## 5 52 1 0.823 0.0485 0.733 0.923
## 7 51 1 0.806 0.0502 0.714 0.911
## 8 50 1 0.790 0.0517 0.695 0.898
## 9 49 2 0.758 0.0544 0.659 0.873
## 10 47 1 0.742 0.0556 0.641 0.859
## 11 46 1 0.726 0.0567 0.623 0.846
## 12 45 2 0.694 0.0585 0.588 0.818
## 13 43 1 0.677 0.0594 0.571 0.804
## 14 42 1 0.661 0.0601 0.553 0.790
## 15 41 1 0.645 0.0608 0.536 0.776
## 17 40 1 0.629 0.0613 0.520 0.762
## 19 39 1 0.613 0.0619 0.503 0.747
## 21 38 2 0.581 0.0627 0.470 0.717
## 22 36 1 0.565 0.0630 0.454 0.702
## 23 35 1 0.548 0.0632 0.438 0.687
## 25 34 1 0.532 0.0634 0.421 0.672
## 26 33 1 0.516 0.0635 0.406 0.657
## 27 32 2 0.484 0.0635 0.374 0.626
## 28 30 1 0.468 0.0634 0.359 0.610
## 29 29 1 0.452 0.0632 0.343 0.594
## 32 28 1 0.435 0.0630 0.328 0.578
## 33 27 1 0.419 0.0627 0.313 0.562
## 35 26 1 0.403 0.0623 0.298 0.546
## 37 25 1 0.387 0.0619 0.283 0.529
## 38 24 1 0.371 0.0613 0.268 0.513
## 41 23 1 0.355 0.0608 0.254 0.496
## 42 22 1 0.339 0.0601 0.239 0.480
## 43 21 2 0.306 0.0585 0.211 0.446
## 44 19 1 0.290 0.0576 0.197 0.428
## 49 18 2 0.258 0.0556 0.169 0.394
## 52 16 2 0.226 0.0531 0.142 0.358
## 61 14 1 0.210 0.0517 0.129 0.340
## 72 13 1 0.194 0.0502 0.116 0.322
<- survfit(Surv(strikes$T,strikes$status) ~PROD, data=strikes, type = "kaplan-meier") #Estimación Kaplan Meier por grupos
strikes.km2#summary(strikes.km2) #Resumen estadístico
fortify(strikes.km2) #Resumen la información
## time n.risk n.event n.censor surv std.err upper lower
## 1 5 2 1 0 0.50000000 0.70710678 1.0000000 0.125048827
## 2 49 1 1 0 0.00000000 Inf NA NA
## 3 15 3 1 0 0.66666667 0.40824829 1.0000000 0.299507130
## 4 61 2 1 0 0.33333333 0.81649658 1.0000000 0.067278391
## 5 98 1 0 1 0.33333333 0.81649658 1.0000000 0.067278391
## 6 3 11 1 0 0.90909091 0.09534626 1.0000000 0.754133845
## 7 17 10 1 0 0.81818182 0.14213381 1.0000000 0.619248987
## 8 19 9 1 0 0.72727273 0.18463724 1.0000000 0.506446765
## 9 28 8 1 0 0.63636364 0.22792115 0.9947460 0.407097577
## 10 72 7 1 0 0.54545455 0.27524094 0.9355006 0.318033634
## 11 99 6 0 1 0.54545455 0.27524094 0.9355006 0.318033634
## 12 104 5 0 1 0.54545455 0.27524094 0.9355006 0.318033634
## 13 114 4 0 1 0.54545455 0.27524094 0.9355006 0.318033634
## 14 152 3 0 1 0.54545455 0.27524094 0.9355006 0.318033634
## 15 153 2 0 1 0.54545455 0.27524094 0.9355006 0.318033634
## 16 216 1 0 1 0.54545455 0.27524094 0.9355006 0.318033634
## 17 2 9 1 0 0.88888889 0.11785113 1.0000000 0.705557502
## 18 12 8 2 0 0.66666667 0.23570226 1.0000000 0.420028359
## 19 21 6 2 0 0.44444444 0.37267800 0.9226597 0.214088528
## 20 27 4 1 0 0.33333333 0.47140452 0.8397287 0.132317867
## 21 38 3 1 0 0.22222222 0.62360956 0.7544056 0.065459105
## 22 42 2 1 0 0.11111111 0.94280904 0.7051443 0.017508018
## 23 117 1 0 1 0.11111111 0.94280904 0.7051443 0.017508018
## 24 2 3 1 0 0.66666667 0.40824829 1.0000000 0.299507130
## 25 25 2 1 0 0.33333333 0.81649658 1.0000000 0.067278391
## 26 85 1 0 1 0.33333333 0.81649658 1.0000000 0.067278391
## 27 7 8 1 0 0.87500000 0.13363062 1.0000000 0.673381937
## 28 9 7 1 0 0.75000000 0.20412415 1.0000000 0.502701841
## 29 13 6 1 0 0.62500000 0.27386128 1.0000000 0.365400279
## 30 14 5 1 0 0.50000000 0.35355339 0.9998048 0.250048822
## 31 26 4 1 0 0.37500000 0.45643546 0.9173812 0.153289602
## 32 29 3 1 0 0.25000000 0.61237244 0.8302184 0.075281393
## 33 52 2 1 0 0.12500000 0.93541435 0.7818729 0.019984067
## 34 130 1 0 1 0.12500000 0.93541435 0.7818729 0.019984067
## 35 9 6 1 0 0.83333333 0.18257419 1.0000000 0.582654795
## 36 37 5 1 0 0.66666667 0.28867513 1.0000000 0.378606461
## 37 41 4 1 0 0.50000000 0.40824829 1.0000000 0.224630348
## 38 49 3 1 0 0.33333333 0.57735027 1.0000000 0.107507139
## 39 52 2 1 0 0.16666667 0.91287093 0.9974380 0.027849128
## 40 119 1 0 1 0.16666667 0.91287093 0.9974380 0.027849128
## 41 1 18 1 0 0.94444444 0.05716620 1.0000000 0.844338248
## 42 2 17 1 0 0.88888889 0.08333333 1.0000000 0.754942745
## 43 3 16 3 0 0.72222222 0.14617634 0.9618257 0.542307142
## 44 4 13 1 0 0.66666667 0.16666667 0.9242206 0.480885649
## 45 8 12 1 0 0.61111111 0.18802536 0.8834209 0.422739379
## 46 11 11 1 0 0.55555556 0.21081851 0.8398013 0.367517864
## 47 22 10 1 0 0.50000000 0.23570226 0.7935972 0.315021269
## 48 23 9 1 0 0.44444444 0.26352314 0.7449528 0.265158882
## 49 27 8 1 0 0.38888889 0.29546842 0.6939508 0.217932680
## 50 32 7 1 0 0.33333333 0.33333333 0.6406378 0.173438256
## 51 33 6 1 0 0.27777778 0.38005848 0.5850647 0.131883705
## 52 35 5 1 0 0.22222222 0.44095855 0.5273902 0.093636007
## 53 43 4 2 0 0.11111111 0.66666667 0.4104169 0.030080829
## 54 44 2 1 0 0.05555556 0.97182532 0.3732044 0.008270053
## 55 100 1 0 1 0.05555556 0.97182532 0.3732044 0.008270053
## 56 3 2 1 0 0.50000000 0.70710678 1.0000000 0.125048827
## 57 10 1 1 0 0.00000000 Inf NA NA
## strata
## 1 -0.10443
## 2 -0.10443
## 3 -0.05467
## 4 -0.05467
## 5 -0.05467
## 6 -0.03957
## 7 -0.03957
## 8 -0.03957
## 9 -0.03957
## 10 -0.03957
## 11 -0.03957
## 12 -0.03957
## 13 -0.03957
## 14 -0.03957
## 15 -0.03957
## 16 -0.03957
## 17 -0.007
## 18 -0.007
## 19 -0.007
## 20 -0.007
## 21 -0.007
## 22 -0.007
## 23 -0.007
## 24 0.00535
## 25 0.00535
## 26 0.00535
## 27 0.01138
## 28 0.01138
## 29 0.01138
## 30 0.01138
## 31 0.01138
## 32 0.01138
## 33 0.01138
## 34 0.01138
## 35 0.02299
## 36 0.02299
## 37 0.02299
## 38 0.02299
## 39 0.02299
## 40 0.02299
## 41 0.0645
## 42 0.0645
## 43 0.0645
## 44 0.0645
## 45 0.0645
## 46 0.0645
## 47 0.0645
## 48 0.0645
## 49 0.0645
## 50 0.0645
## 51 0.0645
## 52 0.0645
## 53 0.0645
## 54 0.0645
## 55 0.0645
## 56 0.07427
## 57 0.07427
ggsurvplot(fit =strikes.km, data =strikes, conf.int = TRUE, title = "Curva de Supervivencia", xlab = "Tiempo(días)", ylab = "Probabilidad de supervivencia",
legend.title = "Estimación",legend.labs = "Kaplan-Meier")
La estimación de la función de riesgo acumulado se puede estimar de dos formas:
\[\lambda(t)=\frac{f(t)}{S(t)}=-\frac{d}{dt}\ln S(t)\] \[\begin{aligned} \Lambda (t)= \int_0^t \lambda(u)du&=-\ln S(u)\Big|_0^t \\ &=-(\ln S(t)-\ln S(0)) =-(\ln S(t)-\ln (1)) \\ &=-\ln S(t) \end{aligned}\]
ggsurvplot(strikes.km, fun = "cumhaz", xlab = "Tiempo (días)", censor = T,
ylab = "Riesgo Acumulado", title = "Riesgo Acumulado", legend.title = "Duración de huelgas contractuales")
## Warning in if (censor & any(df$n.censor >= 1)) {: the condition has length > 1
## and only the first element will be used
print(strikes.km, print.rmean = TRUE)
## Call: survfit(formula = strikes.surv ~ 1, data = strikes, type = "kaplan-meier")
##
## n events *rmean *se(rmean) median 0.95LCL 0.95UCL
## 62.00 50.00 60.50 9.89 27.00 21.00 41.00
## * restricted mean with upper limit = 216
Tanto como para la estimación de la mediana, tanto como los percentiles se utiliza la función , los argumentos de la función son los siguientes:
x : Objeto tipo Survfit. probs : Vector de cuantiles que se desea estimar. conft.int* : Indicador(TRUE/FALSE) para estimar el intervalo de confianza para los cuantiles.
#Mediana
quantile(strikes.km,0.5)$quantile #La mediana es 27 días
## 50
## 27
Empecemos estimando algunos modelos de duración sin covariables. Esto sería útil para explorar la dependencia de la duración de un proceso.
¿Qué ocurre cuando la duración del suceso se prolonga?
En primer lugar, que a medida que dure más un suceso más riesgo habrá de que haya un tránsito: Dependencia de la duración positiva.
En segundo lugar, que a medida que dure más un suceso menor riesgo habrá de que haya un tránsito: Dependencia de la duración negativa.
library(rms)
## Loading required package: Hmisc
## Loading required package: lattice
## Loading required package: Formula
##
## Attaching package: 'Hmisc'
## The following objects are masked from 'package:dplyr':
##
## src, summarize
## The following objects are masked from 'package:base':
##
## format.pval, units
## Loading required package: SparseM
##
## Attaching package: 'SparseM'
## The following object is masked from 'package:base':
##
## backsolve
##
## Attaching package: 'rms'
## The following objects are masked from 'package:car':
##
## Predict, vif
# Estimación del modelo exponencial
<-psm(Surv(T,status)~1,strikes,dist="exponential") #Parametric Survival Model
exp.model exp.model
## Parametric Survival Model: Exponential Distribution
##
## psm(formula = Surv(T, status) ~ 1, data = strikes, dist = "exponential")
##
## Model Likelihood Discrimination
## Ratio Test Indexes
## Obs 62 LR chi2 0.00 R2 0.000
## Events50 d.f. 0 Dxy 0.000
## sigma 1 g 0.000
## gr 1.000
##
## Coef S.E. Wald Z Pr(>|Z|)
## [1,] 3.9688 0.1414 28.06 <0.0001
##
Calcule el AIC en el modelo exponencial para su uso posterior en la comparación de modelos.
<- exp.model$loglik[2]
ll.exp<- nrow(strikes)-exp.model$df.residual-1
df.exp<- -2*ll.exp+2*df.exp+1
aic.exp aic.exp
## [1] 497.8781
<-Survival(exp.model)
S<-seq(0,200,by=1)
timesplot(times,S(times,exp.model$coef),xlab="Días",ylab="S(t)",main="Función de supervivencia exponencial",type='l')
#Alternativamente puedes usar flexsurvreg() del pkg flexsurv
<- flexsurvreg(Surv(T,status) ~ 1, data =strikes, dist = "exp") #Ajuste exponencial
flex flex
## Call:
## flexsurvreg(formula = Surv(T, status) ~ 1, data = strikes, dist = "exp")
##
## Estimates:
## est L95% U95% se
## rate 0.01890 0.01432 0.02493 0.00267
##
## N = 62, Events: 50, Censored: 12
## Total time at risk: 2646
## Log-likelihood = -248.4391, df = 1
## AIC = 498.8781
plot(flex, type = "survival", ci = F, main = "Probabilidad de Supervivencia",
conf.int = F, col = 1, col.obs = 2, xlab = "Tiempo", ylab = "Probabilidad de Supervivencia")
Gráfica de riesgio acumulado:
#Gráfica de riesgo acumulado
plot(flex, type = "cumhaz", ci = F, main = "Riesgo Acumulado", conf.int = F,
col = 3, col.obs = 4, xlab = "Tiempo", ylab = "Riesgo Acumulado")
Compación entre la estimación no-paramétrica y la estimación paramétrica
<- flexsurvreg(Surv(T,status)~1, data=strikes, dist = "exp") %>%
flexggsummary(type = "survival") %>% data.frame
<- survfit(Surv(T,status) ~ 1, data =strikes) %>% fortify
kmgg
ggplot() + geom_line(aes(time, est, col = "Paramétrico"), data = flexgg) + geom_step(aes(time,
col = "No Paramétrico"), data = kmgg) + labs(x="Tiempo(Días)",
surv, y = "Probabilidad de Supervivencia", col = "Ajustes", title = "Comparación entre curvas de supervivencia")
<- flexsurvreg(Surv(T,status)~1,data =strikes, dist = "exp") %>%
flexch summary() %>% data.frame
<-survfit(Surv(T,status)~1,data=strikes) %>% fortify
kmch
ggplot() + geom_line(aes(time,-log(est), col = "Paramétrico"), data = flexch) +geom_step(aes(time,-log(surv), col = "No Paramétrico"), data = kmch) +
labs(x = "Tiempo (Semanas)", y = "Riesgo Acumulado", col = "Ajustes", title = "Comparación entre Riesgo acumulado")
<-psm(Surv(T,status)~1,strikes, dist="weibull")
weibull.model weibull.model
## Parametric Survival Model: Weibull Distribution
##
## psm(formula = Surv(T, status) ~ 1, data = strikes, dist = "weibull")
##
## Model Likelihood Discrimination
## Ratio Test Indexes
## Obs 62 LR chi2 0.00 R2 0.000
## Events 50 d.f. 0 Dxy 0.000
## sigma 1.33954 g 0.000
## gr 1.000
##
## Coef S.E. Wald Z Pr(>|Z|)
## (Intercept) 3.9092 0.1900 20.57 <0.0001
## Log(scale) 0.2923 0.1157 2.53 0.0115
##
# Calculamos el AIC para su uso posterior en la comparación de los modelos
<- weibull.model$loglik[2]
ll.weibull<- nrow(strikes)-weibull.model$df.residual-1
df.weibull<- -2*ll.weibull+2*df.weibull+1
aic.weibull aic.weibull
## [1] 492.5162
# Ploteamos la función de supervivencia y la función hazard para el modelo Weibull
<-Survival(weibull.model)
S
<-seq(0,max(T),by=1)
timespar(mfrow=c(2,1))
plot(times, S(times,weibull.model$coef), xlab="Días",ylab="S(t)",main="Función de supervivencia Weibull",type='l') # plots survival curve at X*Beta hat=?
<-Hazard(weibull.model)
H
plot(times, H(times,weibull.model$coef), xlab="Días",ylab="H(t)",main="Función Hazard Weibull",type='l') # plots survival curve at X*Beta hat=?
<-psm(Surv(T,status)~1,strikes,dist="lognormal")
lognormal.model lognormal.model
## Parametric Survival Model: Log Normal Distribution
##
## psm(formula = Surv(T, status) ~ 1, data = strikes, dist = "lognormal")
##
## Model Likelihood Discrimination
## Ratio Test Indexes
## Obs 62 LR chi2 0.00 R2 0.000
## Events 50 d.f. 0 Dxy 0.000
## sigma 1.539578 g 0.000
## gr 1.000
##
## Coef S.E. Wald Z Pr(>|Z|)
## (Intercept) 3.2619 0.2008 16.24 <0.0001
## Log(scale) 0.4315 0.1053 4.10 <0.0001
##
#Calculamos el AIC para su uso posterior en la comparación de los modelos
<-lognormal.model$loglik[2]
ll.lognormal<-nrow(strikes)-lognormal.model$df.residual-1
df.lognormal<- -2*ll.lognormal+2*df.lognormal+1
aic.lognormal aic.lognormal
## [1] 483.8879
#Ploteamos la función de supervivencia y la función hazard para el modelo logNormal
<-Survival(lognormal.model)
S<- seq(0,max(T),by=1)
times
par(mfrow=c(2,1))
plot(times,S(times,lognormal.model$coef), xlab="Días",ylab="S(t)",main="Función de supervivencia lognormal",type='l') # plots survival curve at X*Beta hat=?
<-Hazard(lognormal.model)
H
plot(times,H(times,lognormal.model$coef), xlab="Días",ylab="H(t)",main="Función Hazard lognormal",type='l') # plots survival curve at X*Beta hat=?
<- psm(Surv(T, status) ~ 1, strikes, dist="logistic")
logistic.model logistic.model
## Parametric Survival Model: Logistic Distribution
##
## psm(formula = Surv(T, status) ~ 1, data = strikes, dist = "logistic")
##
## Model Likelihood Discrimination
## Ratio Test Indexes
## Obs 62 LR chi2 0.00 R2 0.000
## Events 50 d.f. 0 Dxy 0.000
## sigma 28.09632 g 0.000
## gr 1.000
##
## Coef S.E. Wald Z Pr(>|Z|)
## (Intercept) 36.9320 6.0694 6.08 <0.0001
## Log(scale) 3.3356 0.1250 26.68 <0.0001
##
#Calculamos el AIC para su uso posterior en la comparación de los modelos
<- logistic.model$loglik[2]
ll.logistic<- nrow(strikes)-logistic.model$df.residual-1
df.logistic<- -2*ll.logistic+2*df.logistic+1
aic.logistic aic.logistic
## [1] 566.4571
#Ploteamos la función de supervivencia y la función hazard para el modelo logistic
<-Survival(logistic.model)
S<-seq(0,max(T),by=1)
times
par(mfrow=c(2,1))
plot(times,S(times,logistic.model$coef), xlab="Días",ylab="S(t)",main="Función de supervivencia logistic",type='l') # plots survival curve at X*Beta hat=?
<-Hazard(logistic.model)
H
plot(times,H(times,logistic.model$coef), xlab="Días",ylab="H(t)",main="Función Hazard logistico",type='l') # plots survival curve at X*Beta hat=?
<-psm(Surv(T,status)~1,strikes,dist="loglogistic")
loglogistic.model loglogistic.model
## Parametric Survival Model: Log logistic Distribution
##
## psm(formula = Surv(T, status) ~ 1, data = strikes, dist = "loglogistic")
##
## Model Likelihood Discrimination
## Ratio Test Indexes
## Obs 62 LR chi2 0.00 R2 0.000
## Events 50 d.f. 0 Dxy 0.000
## sigma 0.8973768 g 0.000
## gr 1.000
##
## Coef S.E. Wald Z Pr(>|Z|)
## (Intercept) 3.2431 0.1977 16.41 <0.0001
## Log(scale) -0.1083 0.1188 -0.91 0.3619
##
#Calculamos el AIC para su uso posterior en la comparación de los modelos
<-loglogistic.model$loglik[2]
ll.loglogistic<-nrow(strikes)-loglogistic.model$df.residual-1
df.loglogistic<- -2*ll.loglogistic+2*df.loglogistic+1
aic.loglogistic aic.loglogistic
## [1] 484.2037
# Ploteamos la función de supervivencia y la función hazard para el modelo logistic
<-Survival(loglogistic.model)
S<-seq(0,max(T),by=1)
times
par(mfrow=c(2,1))
plot(times,S(times,loglogistic.model$coef), xlab="Días",ylab="S(t)",main="Función de supervivencia loglogistic",type='l') # plots survival curve at X*Beta hat=?
<-Hazard(loglogistic.model)
H
plot(times, H(times,loglogistic.model$coef), xlab="Días",ylab="H(t)",main="Función Hazard loglogistic",type='l') # plots survival curve at X*Beta hat=?
Podemos usar el criterio AIC como herramienta para comparar los modelos. El modelo con el AIC más bajo es mejor.
Con base en esta comparación resulta que el modelo lognormal es el mejor modelo.
<- rbind(aic.exp,aic.weibull,aic.lognormal,aic.logistic,aic.loglogistic)
AIC.compare
AIC.compare
## [,1]
## aic.exp 497.8781
## aic.weibull 492.5162
## aic.lognormal 483.8879
## aic.logistic 566.4571
## aic.loglogistic 484.2037
<-strikes
datosflex <-c("exp", "weibull", "lognormal","llogis", "gompertz", "genf")
Dist<-Surv(datosflex$T,datosflex$status)
data.Surv
# Inicia SCRIPT#
<-sapply(Dist, function(x) flexsurvreg(data.Surv ~1,dist = x), USE.NAMES = T,simplify = F)
model
model
## $exp
## Call:
## flexsurvreg(formula = data.Surv ~ 1, dist = x)
##
## Estimates:
## est L95% U95% se
## rate 0.01890 0.01432 0.02493 0.00267
##
## N = 62, Events: 50, Censored: 12
## Total time at risk: 2646
## Log-likelihood = -248.4391, df = 1
## AIC = 498.8781
##
##
## $weibull
## Call:
## flexsurvreg(formula = data.Surv ~ 1, dist = x)
##
## Estimates:
## est L95% U95% se
## shape 0.7465 0.5951 0.9366 0.0864
## scale 49.8583 34.3535 72.3608 9.4753
##
## N = 62, Events: 50, Censored: 12
## Total time at risk: 2646
## Log-likelihood = -244.7581, df = 2
## AIC = 493.5162
##
##
## $lognormal
## Call:
## flexsurvreg(formula = data.Surv ~ 1, dist = x)
##
## Estimates:
## est L95% U95% se
## meanlog 3.262 2.868 3.656 0.201
## sdlog 1.540 1.252 1.893 0.162
##
## N = 62, Events: 50, Censored: 12
## Total time at risk: 2646
## Log-likelihood = -240.4439, df = 2
## AIC = 484.8879
##
##
## $llogis
## Call:
## flexsurvreg(formula = data.Surv ~ 1, dist = x)
##
## Estimates:
## est L95% U95% se
## shape 1.114 0.883 1.406 0.132
## scale 25.612 17.386 37.731 5.063
##
## N = 62, Events: 50, Censored: 12
## Total time at risk: 2646
## Log-likelihood = -240.6019, df = 2
## AIC = 485.2037
##
##
## $gompertz
## Call:
## flexsurvreg(formula = data.Surv ~ 1, dist = x)
##
## Estimates:
## est L95% U95% se
## shape -0.02119 -0.03271 -0.00968 0.00588
## rate 0.03746 0.02549 0.05504 0.00736
##
## N = 62, Events: 50, Censored: 12
## Total time at risk: 2646
## Log-likelihood = -238.7954, df = 2
## AIC = 481.5909
##
##
## $genf
## Call:
## flexsurvreg(formula = data.Surv ~ 1, dist = x)
##
## Estimates:
## est L95% U95% se
## mu 2.89e+00 2.11e+00 3.68e+00 4.00e-01
## sigma 1.56e+00 1.24e+00 1.96e+00 1.81e-01
## Q -5.34e-01 -1.49e+00 4.17e-01 4.85e-01
## P 5.20e-03 2.77e-46 9.74e+40 2.64e-01
##
## N = 62, Events: 50, Censored: 12
## Total time at risk: 2646
## Log-likelihood = -239.8512, df = 4
## AIC = 487.7024
Curvas de supervivencia
plot(model[[1]], ci = F, conf.int = F, lty = 2, main = "Ajuste Paramétrico",
xlab = "Tiempo", ylab = "Probabilidad de Supervivencia")
for (i in 2:length(Dist)) plot(model[[i]], ci = F, conf.int = F, add = T, col = i +
1, lty = i)
## Warning in if (!add) {: the condition has length > 1 and only the first element
## will be used
## Warning in if (!add) {: the condition has length > 1 and only the first element
## will be used
## Warning in if (!add) {: the condition has length > 1 and only the first element
## will be used
## Warning in if (!add) {: the condition has length > 1 and only the first element
## will be used
## Warning in if (!add) {: the condition has length > 1 and only the first element
## will be used
legend("topright", c("KM", Dist), lty = 1:(length(Dist) + 1), col = 1:(length(Dist) +
1))
Curvas de riesgo acumulado
plot(model[[1]], ci = F, conf.int = F, lty = 2, main = "Ajuste Paramétrico",
xlab = "Tiempo", ylab = "Riesgo Acumulado", type = "cumhaz")
for (i in 2:length(Dist)) plot(model[[i]], ci = F, conf.int = F, add = T, col = i +
1, lty = i, type = "cumhaz")
## Warning in if (!add) {: the condition has length > 1 and only the first element
## will be used
## Warning in if (!add) {: the condition has length > 1 and only the first element
## will be used
## Warning in if (!add) {: the condition has length > 1 and only the first element
## will be used
## Warning in if (!add) {: the condition has length > 1 and only the first element
## will be used
## Warning in if (!add) {: the condition has length > 1 and only the first element
## will be used
legend("topright", c("KM", Dist), lty = 1:(length(Dist) + 1), col = 1:(length(Dist) +
1))
Resumen tabla de criterios de información
<-strikes
datosflex<- Surv(datosflex$T, datosflex$status)
data.Surv <- c("exp", "weibull","lognormal", "llogis", "gompertz", "genf")
Dist
# Inicia Script
<-sapply(Dist, function(x) flexsurvreg(data.Surv ~ 1+PROD, data = datosflex,dist = x), USE.NAMES = T, simplify = F)
model
<-sapply(model, function(x) c(AIC = AIC(x), BIC = BIC(x), LogLik = logLik(x)),
AIC.modelsimplify = T)
#AIC.model
# Ordenados por menor AIC
order(AIC.model["AIC", ])] AIC.model[,
## gompertz lognormal llogis genf weibull exp
## AIC 476.2356 479.3866 480.3795 483.2334 484.5031 485.5954
## BIC 482.6170 485.7680 486.7609 493.8691 490.8845 489.8496
## LogLik -235.1178 -236.6933 -237.1897 -236.6167 -239.2516 -240.7977
En ocasiones nos interesa modelar el efecto de la presencia de un vector de covariables o variables explicativas sobre el tiempo de supervivencia.
<-psm(Surv(T,status)~1+PROD,strikes,dist="weibull")
weibull.model weibull.model
## Parametric Survival Model: Weibull Distribution
##
## psm(formula = Surv(T, status) ~ 1 + PROD, data = strikes, dist = "weibull")
##
## Model Likelihood Discrimination
## Ratio Test Indexes
## Obs 62 LR chi2 11.01 R2 0.163
## Events 50 d.f. 1 Dxy 0.224
## sigma 1.215848 Pr(> chi2) 0.0009 g 0.712
## gr 2.038
##
## Coef S.E. Wald Z Pr(>|Z|)
## (Intercept) 4.0221 0.1862 21.60 <0.0001
## PROD -13.6972 4.0794 -3.36 0.0008
## Log(scale) 0.1954 0.1164 1.68 0.0930
##
# Ploteamos la función de supervivencia y la función Hazard del modelo Weibull en la media xbeta
<-c(1,mean(PROD))
xbar
<-xbar%*%weibull.model$coefficients
xbarbeta
<-Survival(weibull.model)
S
#times<-seq(0,max(T),by=1)
<-seq(0,200,by=1)
timespar(mfrow=c(2,1))
plot(times, S(times,xbarbeta), xlab="Días",ylab="S(t)",main="Función de supervivencia Weibull",type='l') # plots survival curve at X*Beta hat
## Warning in t.trans - lp: Recycling array of length 1 in vector-array arithmetic is deprecated.
## Use c() or as.vector() instead.
<-Hazard(weibull.model)
H
plot(times,H(times,xbarbeta),xlab="Días",ylab="H(t)",main="Función Hazard Weibull",type='l') # plots survival curve at X*Beta hat
## Warning in t.trans - lp: Recycling array of length 1 in vector-array arithmetic is deprecated.
## Use c() or as.vector() instead.
¿Qué nos dicen los coeficientes
#z = survreg(Surv(tiempo, censuras) ~ 1,dist="weibull") #pkg survival
<-survreg(Surv(T,status)~PROD,strikes,dist="weibull")
zsummary(z)
##
## Call:
## survreg(formula = Surv(T, status) ~ PROD, data = strikes, dist = "weibull")
## Value Std. Error z p
## (Intercept) 4.022 0.186 21.60 < 2e-16
## PROD -13.697 4.079 -3.36 0.00079
## Log(scale) 0.195 0.116 1.68 0.09302
##
## Scale= 1.22
##
## Weibull distribution
## Loglik(model)= -239.3 Loglik(intercept only)= -244.8
## Chisq= 11.01 on 1 degrees of freedom, p= 9e-04
## Number of Newton-Raphson Iterations: 5
## n= 62
#WeibullReg(Surv(T,status)~1+PROD,strikes)
# Parámetros a y b de la distribución de Weibull
<-z$icoef[[1]]
alfa<- z$scale
sigmac(1/sigma, exp(alfa))
## [1] 0.8224712 49.8582984
# Tiempo medio y coeficiente de información de Akaike
#media <- exp(alfa)*gamma(1 + sigma)
#aic <- -2*z$loglik[1]+2*2
#c(media, aic)
Interpretación 1/Scale = Weibull shape parameter. (1/1.22=0.8196)
Interpretación AFT(Accelerated failure time):
Los coeficientes son logaritmos de razones de tiempos de supervivencia, por lo que un coeficiente positivo significa una supervivencia más larga.
interpretación PH(proportional hazards model)
Para traducir el coeficiente en un modelo AFT \((\alpha_j)\) al de un modelo PH \((\beta_j)\),
\((\beta_j =-\alpha_jp)\)
donde \((p)\) es el parámetro de forma.
Para este ejemplo, el coeficiente se multiplica por -1, luego se multiplica por el parámetro de forma (1/parámetro de escala = 1/1.22 para el modelo exponencial).
\(exp(-0,516*-1*1/1.22) = 75135.56\)
Esta es la razón de riesgo que compara x y x+1.
El modelo bien especificado tendrá una función de riesgo acumulativo que comienza en cero y aumenta de forma lineal. Por ejemplo, aquí comparamos las funciones de riesgo acumulativo para los modelos weibull versus lognormal
# Reestimamos el modelo Weibull
<-psm(Surv(T,status)~1,strikes, dist="weibull")
weibull.model weibull.model
## Parametric Survival Model: Weibull Distribution
##
## psm(formula = Surv(T, status) ~ 1, data = strikes, dist = "weibull")
##
## Model Likelihood Discrimination
## Ratio Test Indexes
## Obs 62 LR chi2 0.00 R2 0.000
## Events 50 d.f. 0 Dxy 0.000
## sigma 1.33954 g 0.000
## gr 1.000
##
## Coef S.E. Wald Z Pr(>|Z|)
## (Intercept) 3.9092 0.1900 20.57 <0.0001
## Log(scale) 0.2923 0.1157 2.53 0.0115
##
# Reestimamos el modelo Lognormal
<-psm(Surv(T, status) ~ 1, strikes, dist="lognormal")
lognormal.model lognormal.model
## Parametric Survival Model: Log Normal Distribution
##
## psm(formula = Surv(T, status) ~ 1, data = strikes, dist = "lognormal")
##
## Model Likelihood Discrimination
## Ratio Test Indexes
## Obs 62 LR chi2 0.00 R2 0.000
## Events 50 d.f. 0 Dxy 0.000
## sigma 1.539578 g 0.000
## gr 1.000
##
## Coef S.E. Wald Z Pr(>|Z|)
## (Intercept) 3.2619 0.2008 16.24 <0.0001
## Log(scale) 0.4315 0.1053 4.10 <0.0001
##
# Ploteamos la función de riesgo integrada(cumulative hazard function) para el modelo Weibull
<-Survival(weibull.model)
S
<-seq(0,max(T),by=1)
times
par(mfrow=c(2,1))
plot(times,-log(S(times,weibull.model$coef)), xlab="Días",ylab=" Función de riesgo integrado",main="Función de riesgo integrado Weibull",type='l')
# plots survival curve at X*Beta hat
#Ploteamos la función de riesgo integrado(the integrated hazard function) para el modelo Lognormal
<-Survival(lognormal.model)
S
<-seq(0,max(T),by=1)
times
plot(times,-log(S(times,lognormal.model$coef)), xlab="Days",ylab="Función de riesgo integrado",main="Función de riesgo integrado del modelo lognormal",type='l') # plots survival curve at X*Beta hat
# Basados en esta comparación, resulta que el modelo Weibull model is the best since it comes closest to ya que se acerca más a una formar una línea recta
coxph(Surv(T,status)~PROD,data=strikes)
## Call:
## coxph(formula = Surv(T, status) ~ PROD, data = strikes)
##
## coef exp(coef) se(coef) z p
## PROD 9.217 10069.139 3.410 2.703 0.00686
##
## Likelihood ratio test=7.63 on 1 df, p=0.005735
## n= 62, number of events= 50
Interpretación
Un incremento en una unidad en x=PROD aumenta el riesgo de evento en un factor de 10069.139(10069.139 veces más riesgo en comparación con la línea de base).