7 votos

Trazar intervalo censurados tiempo seguimiento como un gráfico de líneas

Estoy trabajando en un análisis de supervivencia proyecto donde sería útil para visualizar todo el tiempo de seguimiento y horas de los eventos. Los datos se compone de un IDENTIFICADOR, cual de los dos posibles eventos que tenían (a o B), y el momento en el que se tuvo el evento, así como si están o no en intervalos censurados. No censurado los individuos tienen idénticos dos horas de evento, t1 y t2, mientras que censuraron los individuos tienen t1 =/= t2, dando el límite inferior y superior de sus censurado tiempo.

Parece que es así (todas):

ID, eventA, eventB, t1, t2, censored
1, 0, 1, 7, 7, 0
2, 1, 0, 5, 5, 0 
3, 1, 0, 10, 10, 0
4, 0, 1, 4.5, 4.5, 0
5, 1, 0, 2, 8, 1

Donde ID 5 es censurado.

Me gustaría producir una trama como esta:

enter image description here

Esencialmente, hacer que el eje de las X ID, el eje Y el tiempo. Dibuje un segmento de línea de 0 a t1. Entonces, si se está censurado, dibuje otra línea de segmento de t1 a t2. Presumiblemente, si están sin censura, se superponen, lo cual está bien. A continuación, colocar un marcador en t2 para cada tipo de evento, es decir, una X si se está eventA y O si están eventB.

Supongo que hay una forma de hacer esto en R, pero todavía no he realmente envuelto mi mente alrededor de gráficos en R, y la mayoría de los ejemplos de gráficos en el análisis de supervivencia me estoy encontrando KM de curvas. Alguien tiene una idea?

8voto

tricasse Puntos 1610

Debe haber muchas formas de hacer un tiempo de seguimiento de parcelas con intervalo de datos censurados, aunque una rápida búsqueda en Google sólo se encuentra esta imagen en una visión de conjunto de la censura, que se ve un poco ocupado para mi ojo.

Sólo para dar otro punto de vista, he aquí un enfoque utilizando el paquete ggplot2.

require(ggplot2)

# Your example data
dat <- structure(list(ID = 1:5, eventA = c(0L, 1L, 1L, 0L, 1L), 
    eventB = c(1L, 0L, 0L, 1L, 0L), t1 = c(7, 5, 10, 4.5, 2), t2 = c(7, 5, 10, 4.5, 
    8), censored = c(0, 0, 0, 0, 1)), .Names = c("ID", "eventA", 
    "eventB", "t1", "t2", "censored"), class = "data.frame", row.names = c(NA, -5L))

# Create event variable
dat$event <- with(dat, ifelse(eventA, "A", "B"))

# Create id.ordered, which is a factor that is ordered by t2
# This will allow the plot to be ordered by increasing t2, if desired
dat$id.ordered <- factor(x = dat$ID, levels = order(dat$t2, decreasing = T))

# Use ggplot to plot data from dat object
ggplot(dat, aes(x = id.ordered)) + 
    # Plot solid line representing non-interval censored time from 0 to t1
    geom_linerange(aes(ymin = 0, ymax = t1)) + 
    # Plot line (dotted for censored time) representing time from t1 to t2
    geom_linerange(aes(ymin = t1, ymax = t2, linetype = as.factor(censored))) +  
    # Plot points representing event
    # The ifelse() function moves censored marker to middle of interval
    geom_point(aes(y = ifelse(censored, t1 + (t2 - t1) / 2, t2), shape = event), 
        size = 4) +
    # Flip coordinates
    coord_flip() + 
    # Add custom name to linetype scale, 
    # otherwise it will default to "as.factor(censored))"
    scale_linetype_manual(name = "Censoring", values = c(1, 2), 
        labels = c("Not censored", "Interval censored")) +
    # Add custom shape scale.  Change the values to get different shapes.
    scale_shape_manual(name = "Event", values = c(19, 15)) +
    # Add main title and axis labels
    opts(title = "Patient follow-up") + xlab("Patient ID") +  ylab("Days") + 
    # I think the bw theme looks better for this graph, 
    # but leave it out if you prefer the default theme
    theme_bw()

Y el resultado:

Patient follow-up with interval censored data

Cuando la elaboración de gráficos con la línea de tipo, color, tamaño, etc. condicional en los datos, me parece ggplot2 más intuitiva que la base de los gráficos e incluso el enrejado, aunque enrejado es mucho más rápido cuando se grafica de datos más grandes.

No estoy seguro de si es preferible colocar el marcador de eventos en el centro de la censurados intervalo o al final. Elegí el medio aquí, al destacar que el evento no necesariamente se producen cerca de la final del seguimiento.

Anexo

Una vez que usted decida sobre una parcela estándar, y si usted se encuentra haciendo estas parcelas a menudo, puede ser conveniente para envolver en una función y uso R S3 objeto del sistema para el envío de la conspiración de método con una llamada a la plot() genérico. La siguiente no se relacionan directamente a la pregunta original, pero por el bien de otros lectores interesados en añadir métodos a la plot() genérico, voy a incluir aquí. Primero, envuelve el ggplot llamada en una parcela método de la función:

plot.interval.censored <- function(x, title = "Patient follow-up", 
        xlab = "Patient ID", ylab = "Days",
        linetype.values = c(1, 2), shape.values = c(19, 15))
{
    x$event <- with(dat, ifelse(eventA, "A", "B"))
		x$id.ordered <- factor(x = dat$ID, levels = order(dat$t2, decreasing = T))

    out <- ggplot(x, aes(x = id.ordered)) + 
            geom_linerange(aes(ymin = 0, ymax = t1)) + 
            geom_linerange(aes(ymin = t1, ymax = t2, linetype = as.factor(censored))) +  
            geom_point(aes(y = ifelse(censored, t1 + (t2 - t1) / 2, t2), shape = event), 
                    size = 4) +
            coord_flip() + 
            scale_linetype_manual(name = "Censoring", values = linetype.values, 
                    labels = c("Not censored", "Interval censored")) +
            scale_shape_manual(name = "Event", values = shape.values) +
            opts(title = title) + xlab(xlab) +  ylab(ylab) + 
            theme_bw()

    return(out)
}

A continuación, agregue internal.censored a la clase de su objeto de datos:

class(dat) <- c("interval.censored", class(dat))

Ahora, la trama puede ser producido simplemente llamando al:

plot(dat)

Usted puede poner plot.interval.censored() en un paquete, o añadirlo a tu .Rprofile, en cuyo caso se estará siempre disponible para usted cuando usted comience a R en su máquina. La publicación de un paquete puede ser preferible, ya que es más fácil de compartir con los demás o instalar cuando no estás en tu propia máquina. Sin embargo, la edición .Rprofile podría ser más sencillo. Hadley tiene una gran visión de conjunto de la S3 objeto del sistema.

2voto

Brettski Puntos 5485

Bueno, eso fue... bastante fácil. Inspirado en un gráfico sin relación en visualizar esto:

Decidido que añadir marcadores para ambos A y B para la cohorte entera... eran un poco llena de gente, para esto se muestra con marcadores para la A, pero es claramente generalizable. En la orientación mal como bien, pero que no es una cantidad enorme y en el Reino de ocuparse vanamente.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X