Gráfico de predicción diferente de supervivencia coxph y rms cph

9

He creado mi propia versión ligeramente mejorada del termplot que uso en este ejemplo, puedes encontrarla aquí . He publicado anteriormente en SO, pero cuanto más lo pienso, creo que esto probablemente esté más relacionado con la interpretación del modelo de riesgos proporcionales de Cox que con la codificación real.

El problema

Cuando miro un diagrama de Hazard Ratio, espero tener un punto de referencia donde el intervalo de confianza es naturalmente 0 y este es el caso cuando uso el cph () de rms packagepero no cuando uso el coxph () de survival package. ¿Es correcto el comportamiento de coxph () y, de ser así, cuál es el punto de referencia? Además, la variable ficticia en el coxph () tiene un intervalo y el valor es diferente de ?e0

Ejemplo

Aquí está mi código de prueba:

# Load libs
library(survival)
library(rms)

# Regular survival
survobj <- with(lung, Surv(time,status))

# Prepare the variables
lung$sex <- factor(lung$sex, levels=1:2, labels=c("Male", "Female"))
labels(lung$sex) <- "Sex"
labels(lung$age) <- "Age"

# The rms survival
ddist <- datadist(lung)
options(datadist="ddist")
rms_surv_fit <- cph(survobj~rcs(age, 4)+sex, data=lung, x=T, y=T)

Las tramas de cph

Este código:

termplot2(rms_surv_fit, se=T, rug.type="density", rug=T, density.proportion=.05,
          se.type="polygon", yscale="exponential", log="y", 
          xlab=c("Age", "Sex"), 
          ylab=rep("Hazard Ratio", times=2),
          main=rep("cph() plot", times=2),
          col.se=rgb(.2,.2,1,.4), col.term="black")

da esta trama:

cph () termplot2

Las tramas de coxph

Este código:

termplot2(surv_fit, se=T, rug.type="density", rug=T, density.proportion=.05, 
          se.type="polygon", yscale="exponential", log="y", 
          xlab=c("Age", "Sex"), 
          ylab=rep("Hazard Ratio", times=2),
          main=rep("coxph() plot", times=2),
          col.se=rgb(.2,.2,1,.4), col.term="black")

da esta trama:

coxph () termplot2

Actualizar

Como sugirió @Frank Harrell y después de ajustar la sugerencia en su reciente comentario, obtuve:

p <- Predict(rms_surv_fit, age=seq(50, 70, times=20), 
             sex=c("Male", "Female"), fun=exp)
plot.Predict(p, ~ age | sex,
             col="black",
             col.fill=gray(seq(.8, .75, length=5)))

Esto dio esta muy buena trama:

Trama de celosía

Miré el contrast.rms nuevamente después del comentario e intenté este código que dio una trama ... aunque probablemente hay mucho más que se puede hacer :-)

w <- contrast.rms(rms_surv_fit, 
                  list(sex=c("Male", "Female"), 
                       age=seq(50, 70, times=20)))

xYplot(Cbind(Contrast, Lower, Upper) ~ age | sex, 
       data=w, method="bands")

Dio esta trama:

La trama de contraste

ACTUALIZACIÓN 2

El profesor Thernau tuvo la amabilidad de comentar sobre la falta de confianza de la trama:

Las splines de suavizado en coxph, como las de gam, se normalizan de modo que sum (predicción) = 0. Por lo tanto, no tengo un único punto fijo para el cual la varianza es muy pequeña.

Aunque todavía no estoy familiarizado con GAM, esto parece responder a mi pregunta: esto parece ser un problema de interpretación.

Max Gordon
fuente
3
Varios comentarios Primero lea biostat.mc.vanderbilt.edu/Rrms para conocer las diferencias entre rms y paquetes de diseño. En segundo lugar, use plot () en lugar de plot.Predict para guardar el trabajo. En tercer lugar, puede generar fácilmente tramas para ambos sexos, por ejemplo, utilizando Predict (fit, age, sex, fun = exp) # exp = anti-log; luego plot (resultado) o plot (resultado, ~ edad | sexo). No usas "x = NA" en Predict. rms utiliza gráficos de red, por lo que no se aplican los parámetros habituales de gráficos par y mfrow. Vea ejemplos en mi folleto del curso rms en biostat.mc.vanderbilt.edu/rms . Para contrast.rms estudie más la documentación.
Frank Harrell
1
Muchas gracias por tu aporte. He actualizado el código con mejores ejemplos y he añadido prof. La respuesta de Thernau. PD: Estoy muy emocionado de que estés planeando una nueva versión del libro, extender la sección de sesgo de punto de corte será muy útil como referencia
Max Gordon
1
Puede usar ploty en contrastlugar de plot.Predicty contrast.rms. Usaría byo lengthdentro de en seqlugar de timesy daría contrastdos listas para que especifique exactamente lo que se está contrastando. También puede usar sombreado con xYplotbandas de confianza.
Frank Harrell
1
Gracias. Me gusta usar la trama.Predict porque luego obtengo la ayuda adecuada en RStudio, algo que en mi caso es mucho más vital que el tiempo que lleva escribir el nombre completo de la función (usando Autocompletar (pestaña) en realidad no perder tanto tiempo).
Max Gordon

Respuestas:

5

Creo que definitivamente debería haber un punto en el que el intervalo de confianza sea de ancho cero. También puede intentar una tercera forma, que es utilizar únicamente funciones rms. Hay un ejemplo debajo del archivo de ayuda para contrast.rms para obtener una gráfica de razón de riesgo. Comienza con el comentario # muestra estimaciones separadas por tratamiento y sexo. Tendrá que iniciar sesión para obtener la proporción.

Frank Harrell
fuente
1
Gracias por su respuesta. ¿Crees que debería mencionar este problema al profesor? ¿Terry Therneau si se considera un error / mala interpretación? También he examinado las soluciones gráficas en el paquete rms, no entiendo bien el uso de contrast.rms para trazados. La trama.Predict parece hacer una salida similar a termplot pero no puedo hacer que haga exactamente lo que quiero ... ver mi actualización de la pregunta.
Max Gordon el
2
Sería bueno escribirle para preguntarle y decirle gracias por el viaje al aeropuerto que me dio hace unos minutos. Comentaré anteriormente sobre las otras preguntas.
Frank Harrell