0
$\begingroup$

This question already has an answer here:

I want to create a Kaplan-Meier plot using ggplot2 with a number at risk table beneath. The number at risk table should be aligned to the x-axis ticks of the Kaplan-Meier plot.

Here I found how to determine the number at risk with the following result for my example:

   Group.A Group.B
1      630    1220
2      518    1024
3      416     850
4      360     760
5      318     702
6      288     652
7      185     438
8       75     179
9       13      29
10       0       0

But how can I add these numbers at risk aligned to the x-axis ticks beneath the Kaplan-Meier plot (row names of the above shown data frame = year - 1 ... not all rows will be used, since I truncated the plot after 5 years)? The ggkm function does not help me here, since I would like to write my own more flexible plot.

I wrote the following example.

library(survival)
data(colon)
library(Hmisc)

d <- colon[, Cs(time, status, rx)]
rm(colon)
names(d) <- c("days", "event", "group")
d$group <- ifelse(d$group == "Obs", 1, 2)

fit <- survfit(Surv(days,event)~group, data=d)
diff <- survdiff(Surv(days,event)~group, data=d)

risksets <- with(na.omit(d[, Cs(days, event, group)]), table(group, cut(days, seq(0, max(days), by=365) ) ))
number.at.risk <- sapply(1:nrow(risksets), function(i) Reduce("-",  risksets[i,], init=rowSums(risksets)[i], accumulate=TRUE))
number.at.risk <- data.frame(number.at.risk)
names(number.at.risk) <- c("Group.A", "Group.B")
number.at.risk

###
p.value <- round(1 - pchisq(diff$chisq, 1), digits=4)
p.value <- ifelse(p.value < 0.001, "<0.001", paste("= ", p.value))

d.mortality <- data.frame(time=fit$time, surv=fit$surv, strata=summary(fit, censored=T)$strata)
zeros <- data.frame(time=0, surv=1, strata=unique(d.mortality$strata))
d.mortality <- rbind(d.mortality, zeros)
levels(d.mortality$strata) <- c("Group A", "Group B")
d.mortality$surv <- (1-d.mortality$surv)*100 # event free to events and in %
###
g <- ggplot(d.mortality, aes(time, surv, group=strata)) + 
     geom_step(aes(colour=strata), size=1) +
     theme_bw() + # white background
     theme(
          plot.background = element_blank(), 
          panel.grid.major = element_blank(),
          panel.grid.minor = element_blank(),
          panel.border = element_blank(),
          legend.position="none",
          axis.line = element_line(color = 'black'),
          axis.text.x = element_text(size=15),
          axis.text.y = element_text(size=15),
          axis.title.x = element_text(size=17, hjust=.5, vjust=.25, face="bold"),
          axis.title.y = element_text(size=17, hjust=.5, vjust=1.5, face="bold"),
          plot.title = element_text(size=20, hjust=-.1, vjust=1, face="bold")
     ) +
     scale_y_continuous("Cumulative event rate [%]", limits=c(0, 60)) + 
     scale_x_continuous("Time [years]", limits=c(0, 1825), breaks=seq(0, 1825, 365), labels=c(0, 1, 2, 3, 4, 5)) +
     annotate("text", x = 1000, y = 45, label = "Group A") +
     annotate("text", x = 1000, y = 30, label = "Group B") +
     annotate("text", x = 1000, y = 55, label = paste("P ", p.value, "by log-rank test", collapse=""))

print(g)

enter image description here

$\endgroup$

marked as duplicate by chl Aug 6 '15 at 15:24

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • $\begingroup$ I think you missed the risk table. $\endgroup$ – Deep North Aug 7 '15 at 6:30
  • $\begingroup$ ggkm does not work anymore. $\endgroup$ – Deep North Aug 7 '15 at 6:33
  • 1
    $\begingroup$ Please unmark my question as duplicate, I edited it. My question is about: How can I add the risk table data to the ggplot2 (see number.at.risk output above the code example). Maybe this question is better in stackoverflow? $\endgroup$ – Gurkenhals Aug 9 '15 at 4:17