He creado mi propia versión ligeramente mejorada del termplot que utilizo en este ejemplo, puedes encontrarlo aquí . Ya 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 gráfico de Hazard Ratio espero tener un punto de referencia donde el intervalo de confianza sea naturalmente 0 y este es el caso cuando uso el cph() del rms package
pero no cuando uso el coxph() del survival package
. ¿Es correcto el comportamiento de coxph() y si es así cuál es el punto de referencia? Además, la variable ficticia en coxph() tiene un intervalo y el valor es distinto de $e^0$ ?
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 parcelas 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:
Las parcelas 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:
Actualización
Como @Frank Harrell sugirió y después de ajustar a lo largo de la sugerencia en su reciente comentario que tengo:
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 le dio a esta trama muy agradable:
He vuelto a mirar el contrast.rms después del comentario y he probado este código que ha dado una gráfica... aunque probablemente se pueda hacer mucho más :-)
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 parcela:
ACTUALIZACIÓN 2
El profesor Thernau tuvo la amabilidad de comentar la falta de confianza en las parcelas:
Los splines de suavizado en coxph, al igual que los de gam, están normalizados de modo que sum(prediction) =0. Así que no tengo un punto fijo para para el cual la varianza es extra pequeña.
Aunque todavía no estoy familiarizado con la GAM, esto parece responder a mi pregunta: esto parece ser una cuestión de interpretación.
5 votos
Varios comentarios. En primer lugar, leer biostat.mc.vanderbilt.edu/Rrms para las diferencias entre los paquetes rms y Design. En segundo lugar, utilice plot() en lugar de plot.Predict para ahorrar trabajo. Tercero, puede generar fácilmente gráficos para ambos sexos, por ejemplo, usando Predict(fit, age, sex, fun=exp) # exp=anti-log; luego plot(result) o plot(result, ~ age | sex). No se utiliza "x=NA" en Predict. rms utiliza gráficos de rejilla, por lo que no se aplican los parámetros habituales de gráficos de par y mfrow. Vea los ejemplos en el manual de mi curso de rms en biostat.mc.vanderbilt.edu/rms . Para contrastar.rms estudia más la documentación.
1 votos
Muchas gracias por tu aportación. He actualizado el código con mejores ejemplos y he añadido la respuesta del prof. Thernau. PS Estoy muy emocionado de que su planificación de una nueva versión del libro, la ampliación de la sección de sesgo de punto de corte será muy útil como referencia
1 votos
Puede utilizar
plot
ycontrast
en lugar deplot.Predict
ycontrast.rms
. Yo usaríaby
olength
dentro deseq
en lugar detimes
y daríacontrast
dos listas para especificar exactamente lo que se está contrastando. También puede utilizar el sombreado conxYplot
para las bandas de confianza.1 votos
Gracias. Me gusta usar el plot.Predict porque así llego a la ayuda correcta en RStudio - algo que en mi caso es mucho más vital que el tiempo que se tarda en escribir el nombre completo de la función (usando autocompletar (tab) en realidad no pierdo tanto tiempo).