Sys.setenv(LANGUAGE = "en") library("ameld") library("survival") data(eldd) data(eldr)
Authors: r packageDescription("ameld")[["Author"]]
Last modified: r file.info("ameld.Rmd")$mtime
Compiled: r date()
ameld
PackageThe ameld
R package provides a dataset, eldd
,
of patients evaluated for liver transplantation at the
University Hospital of Leipzig from
r paste(strftime(attr(eldd, "period"), "%B %Y"), collapse = " to ")
.
eldr
contains the reference limits for the laboratory measurements used in
eldd
.
The datasets could be loaded as follows:
library("ameld") data(eldd) data(eldr) colnames(eldd) knitr::kable(head(eldd[, 1:10])) knitr::kable(head(eldr))
The ameld
package provides a plot_surv
function that is similar to
survival::plot.survfit()
but uses different defaults:
library("survival") srv <- Surv(eldd$DaysAtRisk, eldd$Deceased) srvfit <- survfit(srv ~ 1) plot_surv( srvfit, main = "Kaplan-Meier Survival Estimate" ) plot_surv( srvfit, cumhaz = TRUE, main = "Cumulative Hazard" )
A more complex example of the survival plot with risk tables
could be generated by combining plot_surv
and plot_table
:
## timepoints of interest times <- c(0, 30, 90) ## calculate risk tables sm <- summary(srvfit, times = times) nrisk <- as.matrix(sm$n.risk) ncumevents <- as.matrix(cumsum(sm$n.event)) rownames(nrisk) <- rownames(ncumevents) <- times ## keep old graphic parameters and restore them afterwards old.par <- par(no.readonly = TRUE) layout(matrix(1:3, nrow = 3), height = c(5, 1, 1)) par(cex.main = 2) plot_surv( srvfit, main = "Kaplan-Meier Survival Estimate to day 90", times = times, xmax = 90 ) par(mar = c(5.1, 4.1, 1.1, 2.1)) plot_table( nrisk, at = times, main = "Number at risk", xaxis = FALSE, cex.text = 1.5, ylabels = FALSE ) par(mar = c(5.1, 4.1, 1.1, 2.1)) plot_table( ncumevents, at = times, main = "Cumulative number of events", xaxis = FALSE, cex.text = 1.5, ylabels = FALSE ) par(old.par)
The $z(log)$-transformation was suggested in @hoffmann2017. It is similar to
common $z$-transformation but standardizes laboratory measurements by their
respective reference or normal values. An R implementation is provided by the
zlog
package [@zlog].
library("zlog") ## transform reference data.frame for zlog r <- eldr[c("Code", "AgeDays", "Sex", "LowerLimit", "UpperLimit")] names(r) <- c("param", "age", "sex", "lower", "upper") r$age <- r$age / 365.25 r <- set_missing_limits(r) ## we just want to standardize laboratory values cn <- colnames(eldd) cnlabs <- cn[grepl("_[SCEFQ1]$", cn)] zeldd <- eldd zeldd[c("Age", "Sex", cnlabs)] <- zlog_df(eldd[, c("Age", "Sex", cnlabs)], r)
We could use the (mean) $z(log)$ values to get a first impression of the influence of these values on survival/non-survival:
## divide data.frame by dead/alive s <- split(zeldd[cnlabs], zeldd$Deceased) names(s) <- c("survived", "dead") ## calculate mean standardized lab values s <- lapply(s, colMeans, na.rm = TRUE) o <- order(s$dead) ## comparison plot col <- palette.colors(2) ## keep old graphic parameters and restore them afterwards old.par <- par(no.readonly = TRUE) par(mar = c(7.1, 4.1, 4.1, 2.1)) plot( s$dead[o], type = "b", pch = 20, lwd = 2, col = col[1], axes = FALSE, ann = FALSE ) lines(s$survived[o], type = "b", pch = 20, lwd = 2, col = col[2]) legend( "bottomright", legend = c("dead", "survived"), col = col, lwd = 2, pch = 20, bty = "n" ) title( main = "Mortality Status vs Mean Standardized Laboratory Values", adj = 0 ) title(xlab = "Laboratory Measurements", adj = 1L, line = 5) title(ylab = "Mean Standardized Values", adj = 1L) r <- range(unlist(s)) axis( 2, at = seq(from = floor(r[1]), to = ceiling(r[2])), lwd.ticks = 0, col = "#808080" ) axis( 1, at = seq_along(o), labels = names(s$dead[o]), las = 2, lwd.ticks = 0L, col = "#808080" ) par(old.par)
We divide our cohort into 5 MELD-score risk categories as described in @wiesner2003. Our observed 90 day mortality is higher than the predicted one, except in the lowest category.
eldd$MELD <- meld( creatinine = as_metric(eldd$CRE_S, "creatinine"), bilirubin = as_metric(eldd$BILI_S, "bilirubin"), inr = eldd$INR_C, dialysis = eldd$Dialysis, cause = "other" ) # Mortality rates and categories as reported in Wiesner et al. 2003 mr <- c(1.9, 6.0, 19.6, 52.6, 71.3) / 100 mcat <- cut( eldd$MELD, breaks = c(-Inf, seq(10, 40, by=10), Inf), labels = c( paste0("[", floor(min(eldd$MELD, na.rm = TRUE)), ",9]"), "[10,20)", "[20,30)", "[30,40)", paste0( "[40,", ceiling(max(eldd$MELD, na.rm = TRUE)), ")") ), right = FALSE ) tbl <- observed_vs_expected_mortality(srv, time = 90, f = mcat, expected = mr) tbl[c("ObservedMortality", "ExpectedMortality")] <- tbl[c("ObservedMortality", "ExpectedMortality")] * 100 knitr::kable( tbl, col.names = c( "Observed deaths (n)", "Expected deaths (n)", "Standardized mortality ratio (SMR)", "Observed mortality (%)", "Expected mortality (%)" ), caption = paste0( "Observed vs MELD-expected 90 day mortality. ", "MELD mortality values are taken from @wiesner2003. ", "All patients censored before day 90 are ignored for ", " the calculation of the MELD-expected deaths. ", "SMR, Standardized mortality ratio = observed deaths/expected deaths." ), digits = 1 )
This work is part of the AMPEL (Analysis and Reporting System for the Improvement of Patient Safety through Real-Time Integration of Laboratory Findings) project.
This measure is co-funded with tax revenues based on the budget adopted by the members of the Saxon State Parliament.
sessionInfo()
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.