kmplot: Survival curves

View source: R/surv.R

kmplotR Documentation

Survival curves

Description

Plot Kaplan-Meier or Cox regression models with optional at-risk table, median survival summary, confidence bands/intervals, pairwise tests, hazard ratios, cumulative incidences, and other features.

Usage

kmplot(
  object,
  data = NULL,
  lty.surv = par("lty"),
  lwd.surv = par("lwd"),
  col.surv = seq_along(object$n),
  mark = 3L,
  lwd.mark = lwd.surv,
  lty.ci = 0,
  lwd.ci = lwd.surv,
  col.ci = col.surv,
  col.band = FALSE,
  alpha.band = 0.5,
  kmdiff = FALSE,
  atrisk.table = TRUE,
  atrisk.lab = NULL,
  atrisk.pad = 0.5,
  atrisk.type = c("atrisk", "events", "atrisk-events", "survival", "survival-ci",
    "percent", "percent-ci", "cuminc", "percent-cuminc", "cuminc-ci",
    "percent-cuminc-ci"),
  atrisk.digits = (!grepl("percent", atrisk.type)) * 2,
  atrisk.lines = TRUE,
  atrisk.lines.adj = NA,
  atrisk.col = !atrisk.lines,
  atrisk.min = NULL,
  strata.lab = NULL,
  strata.expr = NULL,
  strata.order = seq_along(object$n),
  extra.margin = 5,
  mar = NULL,
  median = FALSE,
  digits.median = 0L,
  ci.median = TRUE,
  args.median = list(),
  xaxs = "s",
  xlim = NULL,
  ylim = NULL,
  xaxis.at = pretty(xlim),
  xaxis.lab = xaxis.at,
  atrisk.at = xaxis.at,
  yaxis.at = pretty(0:1),
  yaxis.lab = yaxis.at,
  xlab = "Time",
  ylab = "Probability",
  main = NULL,
  cex.axis = par("cex.axis"),
  cex.atrisk = cex.axis,
  cex.lab = par("cex.lab"),
  cex.main = par("cex.main"),
  legend = !atrisk.table && !is.null(object$strata),
  args.legend = list(),
  median.legend = FALSE,
  lr_test = TRUE,
  tt_test = FALSE,
  test_details = TRUE,
  args.test = list(),
  hr_text = FALSE,
  args.hr = list(),
  events = FALSE,
  pw_test = FALSE,
  args.pw = list(),
  format_pval = TRUE,
  stratify = NULL,
  fun = c("S", "F"),
  times = NULL,
  times.lab = NULL,
  times.type = c("percent", "atrisk", "events", "atrisk-events", "survival",
    "survival-ci", "percent-ci", "cuminc", "percent-cuminc", "cuminc-ci",
    "percent-cuminc-ci"),
  times.digits = (!grepl("percent", times.type)) * 2,
  args.times = list(),
  add = FALSE,
  panel.first = NULL,
  panel.last = NULL,
  ...
)

Arguments

object

an object of class survfit or survfit.coxph; note that for the latter some features are not available, e.g., kmdiff, lr_test, tt_test, hr_text, atrisk.type and/or times.type %in% c("atrisk", "events", "atrisk-events"), etc.

data

(optional) the data frame used to create s, used to obtain some data not available in survfit objects; if not given, object$call$data will be searched for in the sys.frames

lty.surv, lwd.surv, col.surv

line type, width, and color for survival curve(s); colors may be either numeric, color names as character string(s), or hexadecimal string(s)

colors will be assigned to curves in order of strata or may be mapped using a named vector (the names must match the ones given to strata.lab or those that are created by strata); this can be useful to set colors for specific strata levels in multiple plots if some levels are missing; see examples in kmplot_by

mark, lwd.mark

numeric plotting character (pch) or character string, e.g., '', '|'; if mark = 'bump', a mark will be drawn only above the curve; lwd.mark controls the line width when a pch or "bump" is used

lty.ci, lwd.ci, col.ci

line type, width, and color for confidence interval(s); not plotted (i.e., = 0) by default

col.band

color for confidence band(s); either as numeric, color string(s), or hexadecimal string(s); if TRUE, col.surv values will be used; if FALSE, NA, or NULL, no bands will be plotted; also note that this is not a true confidence band; see details

alpha.band

alpha transparency (in [0, 1]) of the band

kmdiff

logical; if TRUE, a confidence band for the difference between two curves is shown; see kmdiff (note that the color can be passed via col.ci and the confidence interval is taken from object$conf.int)

atrisk.table

logical; if TRUE (default), draws at-risk table

atrisk.lab

heading for at-risk table

atrisk.pad

extra padding between plot and at-risk table; alternatively, a vector of padding for each line in the at-risk table, recycled as needed

atrisk.type

a character string giving the type of "at-risk" table to show; one of "atrisk" (number at-risk), "events" (cumulative number of events), "atrisk-events" (both), "survival" (survival probability), "percent" (survival percent), or "cuminc" (cumulative incidence); "survival-ci", "percent-ci", "percent-cuminc", "cuminc-ci", and "percent-cuminc-ci" are similar but add confidence intervals

atrisk.digits

when survival probabilities are shown in at-risk table (see atrisk.type), number of digits past the decimal to keep

atrisk.lines

logical; draw lines next to strata in at-risk table

atrisk.lines.adj

a vector of length 2 giving the left and right adjustment for the at-risk lines in normalized units, e.g., c(0, 1) and c(-0.5, 0.5) doubles the length by extending right-only and equally left and right, respectively

atrisk.col

logical or a vector with colors for at-risk table text; if TRUE, col.surv will be used

atrisk.min

optional integer to replace any at-risk counts < atrisk.min with "---" by default; note that if atrisk.min is named, then names(atrisk.min) will be the replacement string

strata.lab

labels used in legend and at-risk table for strata; if NULL (default), labels created in survfit are used; if only one strata is present, "All" is used by default; if FALSE, labels are not used; if TRUE, labels will be stripped of variable names

strata.expr

an alternative to strata.lab which allows for bquote or expression to be passed to labels for at-risk table; note that strata.expr trumps strata.lab

strata.order

order of strata in legend and at-risk table

extra.margin

increase left margin when strata labels in at-risk table are long (note that this will be overridden by mar)

mar

margins; see mar section in par

median

logical or numeric; if TRUE, median and confidence interval for each curve is added to at-risk table at a calculated position; for more control, use a specific x-coordinate

digits.median

number of digits past the decimal point to keep for median(s)

ci.median

logical; if TRUE, confidence interval for medians are shown

args.median

an optional named list of mtext arguments controlling the median text

additionally, list(x = , y = ) may be given for exact placement (translated to at and line, respectively)

xaxs

style of axis; see details or par

xlim, ylim

x- and y-axis limits

xaxis.at, yaxis.at

positions for x- and y-axis labels and ticks

xaxis.lab, yaxis.lab

x- and y-axis tick labels

atrisk.at

x-coordinates to show at-risk table (default is xaxis.at)

xlab, ylab

x- and y-axis labels

main

title of plot

cex.axis, cex.atrisk

text size for axis tick labels and at-risk table

cex.lab, cex.main

text size for axis and main titles

legend

logical, a vector of x/y coordinates, or a keyword (see legend); if TRUE, the default position is "bottomleft"

args.legend

an optional named list of legend arguments controlling the legend

median.legend

logical; if TRUE, medians (and optionally confidence intervals if ci.median = TRUE) are added to the legend, useful for adding a legend and median without at-risk table

lr_test

logical or numeric; if TRUE, a log-rank test will be performed and the results added to the top-right corner of the plot; if numeric, the value is passed as rho controlling the type of test performed; see survdiff

tt_test

logical; if TRUE, Tarone's trend test will be performed and the resultls added to the top-right corner of the plot; note that this will override lr_test

test_details

logical; if TRUE (default), all test details (test statistic, degrees of freedom, p-value) are shown; if FALSE, only the p-value is shown

args.test

an optional named list of mtext arguments controlling the *_test text; additional text can be appended with list(.prefix = '') or list(.suffix = '')

hr_text

logical; if TRUE, a coxph model is fit, and a summary (hazard ratios, confidence intervals, and Wald p-values) is shown

args.hr

an optional named list of legend arguments controlling the hr_text legend

events

logical; if TRUE and hr_text = TRUE, the total events by group is shown

pw_test

logical; if TRUE, all pairwise tests of survival curves are performed, and p-valuees are shown

args.pw

an optional named list of legend arguments controlling the pw_text legend

format_pval

logical; if TRUE, p-values are formatted with pvalr; if FALSE, no formatting is performed; alternatively, a function can be passed which should take a numeric value and return a character string (or a value to be coerced) for printing

stratify

(dev) strata variables

fun

survival curve transformation, one of "S" or "F" for the usual survival curve or empirical CDF, respectively

times

time points to show additional summaries in a table added to the plot (requires plotr)

times.lab

heading for the times table

times.type

see atrisk.type

times.digits

when survival probabilities are shown in times table (see times.type), number of digits past the decimal to keep

args.times

an optional named list of plotr::tableplot arguments controlling the table appearance and/or location

add

logical; if TRUE, pars are not reset; allows for multiple panels, e.g., when using par(mfrow = c(1, 2))

panel.first

an expression to be evaluated after the plot axes are set up but before any plotting takes place

panel.last

an expression to be evaluated after plotting but before returning from the function

...

additional parameters (font, mfrow, bty, tcl, etc.) passed to par

Details

Line specifications (e.g., lty.surv, lwd.surv, etc.) will be recycled as needed.

If col.band is not NULL, NA, or FALSE, a confidence band is plotted; however, this is not a confidence band in the statistical sense, i.e., a xx-percent chance of containing the entire population of the survival curve which are wider than the point-wise confidence limits. Rather, it refers to a band of color plotted between the confidence limits calculated in the survfit object. That is, the xx-% confidence interval (plotted when lty.ci != 0) and the confidence bands are identical–just two ways of plotting the same invervals.

xaxs is the style of the x-axis; see par. The default for kmplot is "S" which is equivalent to xaxs = "i" but with the maximum xlim value increased by 4%. Other styles for xaxs currently implemented in R are "r" (default for plotting and the previous value for kmplot) and "i" which will not add padding to the ends of the axes.

When saving plots, it is highly recommended to use png, svg, pdf, etc. instead of exporting directly from the R graphics device. Doing so may cause the at-risk table or legend to be mis-aligned.

References

Adapted from http://biostat.mc.vanderbilt.edu/wiki/Main/TatsukiRcode

See Also

kmplot_by; survival:::plot.survfit; kmplot_data_; atrisk_data_; lr_text; lr_pval; points.kmplot; kmdiff; ggsurv

Examples

library('survival')
km1 <- survfit(Surv(time, status) ~ sex, data = colon)
km2 <- survfit(Surv(time, status) ~ I(rx == "Obs") + adhere, data = colon)


## basic usage
kmplot(km1)
kmplot(km1, args.median = list(x = 500, y = 0.2))
kmplot(km1, atrisk.table = FALSE, median.legend = TRUE)
kmplot(km1, fun = 'F')
kmplot(km1, atrisk.col = c('grey50', 'tomato'), test_details = FALSE,
       args.test = list(col = 'red', cex = 1.5, .prefix = 'Log-rank: '))
kmplot(km1, mark = 'bump', atrisk.lines = FALSE, median = TRUE)
kmplot(km1, mark = 'bump', atrisk.lines = FALSE, median = 3500)

## atrisk spacing adjustment
kmplot(km2, atrisk.pad = 3)
kmplot(km2, atrisk.pad = 1:4 / 4)

kmplot(km2, atrisk.table = FALSE, lwd.surv = 2, lwd.mark = 0.5,
       col.surv = 1:4, col.band = c(1, 0, 0, 4))


## table of additional stats
kmplot(km1, times = 1:3 * 1000, times.type = 'percent-ci')
kmplot(km1, times = 1:3 * 1000, times.type = 'percent-ci',
       atrisk.table = FALSE, args.times = list(x = 'bottomright'))
kmplot(km1, times = 0:10 * 250, times.type = 'survival',
       times.digits = 3, times.lab = 'Prob. of survival',
       args.times = list(x = mean(par('usr')[1]), y = 0))


## use stratified models
kmplot(km1, stratify = 'differ')
kmplot(km1, stratify = c('differ', 'adhere'))


## for hazard ratios, use factors to fit the proper cox model
kmplot(survfit(Surv(time, status) ~ factor(sex), data = colon),
       hr_text = TRUE, strata.lab = TRUE)
kmplot(survfit(Surv(time, status) ~ interaction(sex, rx), data = colon),
       hr_text = TRUE, atrisk.table = FALSE, legend = FALSE)
kmplot(survfit(Surv(time, status) ~ interaction(sex, rx), data = colon),
       hr_text = TRUE, atrisk.table = FALSE, legend = FALSE,
       format_pval = function(x) format(x, digits = 2, scipen = 0))


## at-risk and p-value options
kmplot(km2, tt_test = TRUE, test_details = FALSE)
kmplot(km2, tt_test = TRUE, format_pval = format.pval)
kmplot(km1, atrisk.type = 'survival', atrisk.digits = 3L)
kmplot(km1, atrisk.type = 'atrisk-events')
kmplot(survfit(Surv(time, status) ~ rx, data = colon),
       pw_test = TRUE, args.pw = list(text.col = 1:3, x = 'bottomleft'))

## expressions in at-risk table (strata.expr takes precedence)
kmplot(km1, strata.lab = c('\u2640', '\u2642'))
kmplot(km1, strata.lab = c('\u2640', '\u2642'),
               strata.expr = expression(widetilde(ring(Female)),
                                        phantom() >= Male))

## character vectors passed to strata.expr will be parsed
kmplot(km1, strata.expr = c('Sex[Female]', 'Sex[Male]'))
## but not those passed to strata.lab
kmplot(km1, strata.lab  = c('Sex[Female]', 'Sex[Male]'))


## when using mfrow options, use add = TRUE and mar to align axes
mar <- c(9, 6, 2, 2)
op <- par(mfrow = c(1, 2))
kmplot(km1, add = TRUE, mar = mar)
kmplot(km2, add = TRUE, strata.lab = TRUE, mar = mar)
par(mfrow = op)


## survfit.coxph object
cx1 <- coxph(Surv(time, status) ~ sex, data = colon)
cx2 <- coxph(Surv(time, status) ~ sex + adhere, data = colon)
cx3 <- coxph(Surv(time, status) ~ I(rx == "Obs") + adhere + age, data = colon)

kmplot(survfit(cx1))
kmplot(survfit(cx1, data.frame(sex = 0:1)), strata.lab = c('F', 'M'))

nd <- expand.grid(adhere = 0:1, sex = 0:1)
kmplot(survfit(cx2, nd), col.surv = 1:4, strata.lab = do.call(paste, nd))
## compare
kmplot(survfit(Surv(time, status) ~ sex + adhere, data = colon),
       atrisk.type = 'survival')

nd <- data.frame(rx = 'Obs', adhere = 0:1, age = c(30, 30, 70, 70))
kmplot(survfit(cx3, nd), col.surv = 1:4, strata.lab = do.call(paste, nd))


raredd/rawr documentation built on May 9, 2024, 6:14 p.m.