Diff of /R/survplot.R [000000] .. [226bc8]

Switch to side-by-side view

--- a
+++ b/R/survplot.R
@@ -0,0 +1,122 @@
+# survplot.R
+#
+# 2009-02-20
+# Aron Charles Eklund
+# http://www.cbs.dtu.dk
+#
+# depends on "survival" package.
+#
+
+# FUNCTIONS IN THIS FILE ARE THE PART OF survplot PACKAGE (version 0.0.7)
+# CREATED BY Aron Charles Eklund
+
+nrisk <- function(x, times = pretty(x$time)) { 
+  stopifnot(class(x) == 'survfit')
+  if('strata' %in% names(x)) {
+    ns <- length(x$strata)
+    idx <- rep.int(1:ns, x$strata)
+    str.n.risk <- split(x$n.risk, idx)
+    str.times <- split(x$time, idx)
+    m <- sapply(times, function(y) {
+      sapply(1:ns, function(i) {
+        w <- which(str.times[[i]] >= y)[1]
+        ifelse(is.na(w), 0, str.n.risk[[i]][w])
+      })
+    })
+    rownames(m) <- names(x$strata)
+  } else {  # no strata
+    m1 <- sapply(times, function(y) {
+      w <- which(x$time >= y)[1]
+      ifelse(is.na(w), 0, x$n.risk[w])
+    })
+    m <- matrix(m1, nrow = 1)
+  }
+  colnames(m) <- times
+  m
+}
+
+
+addNrisk <- function(x, at = axTicks(1), 
+                     line = 4, hadj = 0.5, 
+                     title = 'Number at risk', title.adj = 0, 
+                     labels, hoff = 5, col = 1) {
+  m <- nrisk(x, times = at)
+  ns <- nrow(m)  # number of strata
+  if(missing(labels)) {
+    if(ns > 1) { 
+      labels <- names(x$strata)
+    } else {
+      labels <- NA
+    }
+  }    
+  label.pad <- paste(rep(' ', hoff), collapse = '') 
+  labels2 <- paste(labels, label.pad, sep = '')
+  labels2[is.na(labels)] <- NA
+  col <- rep(col, length.out = ns)
+  hasTitle <- (!is.null(title)) && (!is.na(title))
+  if(hasTitle) {
+    title(xlab = title, line = line, adj = title.adj)
+  }
+  for (i in 1:ns) {
+    axis(1, at = at, labels = m[i,], 
+         line = line + i + hasTitle - 2, tick = FALSE, 
+         col.axis = col[i], hadj = hadj)
+    axis(1, at = par('usr')[1], labels = labels2[i],
+         line = line + i + hasTitle - 2, tick = FALSE,
+         col.axis = col[i], hadj = 1)
+  }
+  invisible(m)
+}
+
+
+
+survplot <- function(x, data = NULL, subset = NULL, 
+                     snames, stitle, 
+                     col, lty, lwd,
+                     show.nrisk = TRUE, color.nrisk = TRUE,
+                     hr.pos = 'topright', legend.pos = 'bottomleft', ...) {
+  eval(bquote(s <- survfit(x, data = data, subset = .(substitute(subset)))))
+  if('strata' %in% names(s)) {
+    if(missing(stitle)) stitle <- strsplit(deparse(x), " ~ ")[[1]][2]
+    if(missing(snames)) {
+      snames <- names(s$strata)
+      prefx <- paste(strsplit(deparse(x), " ~ ")[[1]][2], '=', sep = '')
+      if(all(substr(snames, 1, nchar(prefx)) == prefx)) {
+        snames <- substr(snames, nchar(prefx) + 1, 100)
+      }
+    }
+    ns <- length(s$strata)
+    stopifnot(length(snames) == ns)
+  } else {    # no strata
+    ns <- 1
+    snames <- NA
+    legend.pos <- NA
+  }
+  if(show.nrisk) {
+    mar <- par('mar')
+    mar[1] <- mar[1] + ns + 0.5
+    opar <- par(mar = mar)
+    on.exit(par(opar))
+  }
+  if(missing(col)) col <- 1:ns
+  if(missing(lty)) lty <- 1
+  if(missing(lwd)) lwd <- par('lwd')
+  plot(s, col = col, lty = lty, lwd = lwd, ...)
+  if(length(legend.pos) > 1 || !is.na(legend.pos)) {
+    legend(legend.pos, legend = snames, title = stitle,
+           col = col, lty = lty, lwd = lwd, bty = 'n')
+  }
+  if(ns == 2) {
+    eval(bquote(cox <- summary(coxph(x, data = data, subset = .(substitute(subset))))))
+    hr <- format(cox$conf.int[1, c(1, 3, 4)], digits = 2)
+    p <- format(cox$sctest[3], digits = 2)
+    txt1 <- paste('HR = ', hr[1], ' (', hr[2], ' - ', hr[3], ')', sep = '')
+    txt2 <- paste('logrank P =', p)
+    legend(hr.pos, legend = c(txt1, txt2), bty = 'n')
+  }
+  if(show.nrisk) {
+    addNrisk(s, labels = snames,
+             col = if(color.nrisk) col else 1)
+  }
+  if(ns == 2) return(invisible(c(txt1, txt2)))
+}