Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added aki.units() method #6

Merged
merged 5 commits into from Oct 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .Rbuildignore
Expand Up @@ -14,3 +14,4 @@
^\.png$
^README_cache/
^codecov\.yml$
^resources$
8 changes: 6 additions & 2 deletions DESCRIPTION
Expand Up @@ -21,12 +21,16 @@ License: MIT + file LICENSE
URL: https://github.com/alwinw/epocakir
BugReports: https://github.com/alwinw/epocakir/issues
Depends:
R
R (>= 3.5.0)
Imports:
dplyr,
tidyselect,
tibble,
forcats
forcats,
ellipsis,
rlang,
units,
lubridate
Suggests:
testthat,
covr
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Expand Up @@ -3,4 +3,5 @@
S3method(aki,default)
S3method(aki,numeric)
S3method(aki,ts)
S3method(aki,units)
export(aki)
63 changes: 53 additions & 10 deletions R/aki.R
@@ -1,24 +1,67 @@
.sCr2metric <- function(SCr) {
if (grepl("mol", units::deparse_unit(SCr))) {
return(units::set_units(SCr * units::set_units(113.120, "g/mol"), "mg/dl"))
} else {
return(units::set_units(SCr, "mg/dl"))
}
}

#' Codify AKI from Serum Creatinine and/or Urine Output
#'
#' Some additional details
#' Using KDIGO Clinical Practice Guideline for Acute Kidney Injury
#' Volume 2 | Issue 1 | March 2012
#'
#' @param x numeric number
#' Provided a series of Serum Creatinine readings and/or Urine Output, aki()
#' calculates whether or not a patient has AKI. The staging (1, 2, 3) of AKI is
#' also calculated
#'
#' @return
#' @param data A data.frame with the data needed for serum creatinine (SCr)
#' and/or urine output (UO)
#' @param SCr The variable name, e.g. "cr", to be used for determining
#' AKI based on creatinine level. A numeric vector or time series of
#' serum creatinine values if the data argument is unused
#' @param UO The variable name, e.g. "urine", to be used for determining
#' AKI based on urine output. A numeric vector or time series of
#' urine output values if the data argument is unused
#' @param bCr The variable name, e.g. "baseline_cr", to be used for determining
#' AKI based on urine output. A single numeric value of
#' baseline creatinine if the data argument is unused
#' @param units (character) Units of SCr and UO metric (mg/dl) or SI (umol/l)
#' #TOFIX, consider changing to a list
#' @param na.rm (logical) If TRUE, missing values are removed
#' @param ... Further optional arguments that will be passed to method.
#'
#' @examples
#' aki(seq(60, 200, by = 20))
#' aki(SCr = seq(60, 200, by = 20), bCr = 50)
#' @export
aki <- function(x, ...) {
UseMethod("aki", x)
aki <- function(...) {
ellipsis::check_dots_used()
UseMethod("aki")
}

.aki_stages <- factor(c("AKI Stage 1", "AKI Stage 2", "AKI Stage 3", "No AKI"))

#' @rdname aki
#' @export
aki.numeric <- function(SCr, bCr = NULL, na.rm = FALSE) {
aki.numeric <- function(SCr, bCr = NULL, units = "umol/l", na.rm = FALSE, ...) {
SCr <- units::as_units(SCr, units)
if (is.null(bCr)) {
bCr <- min(SCr, na.rm = na.rm) # Must be run after as_units(SCr, ...)
}
else {
bCr <- units::as_units(bCr, units)
}
aki_stages <- aki.units(SCr = SCr, bCr = bCr, na.rm = na.rm)
return(aki_stages)
}

#' @rdname aki
#' @export
aki.units <- function(SCr, bCr = NULL, na.rm = FALSE, ...) {
if (is.null(bCr)) bCr <- min(SCr, na.rm = na.rm)
aki_stages <- dplyr::case_when(
.sCr2metric(SCr) >= units::set_units(4.0, mg / dl) ~ .aki_stages[3],
SCr >= 3.0 * bCr ~ .aki_stages[3],
SCr >= 2.0 * bCr ~ .aki_stages[2],
SCr >= 1.5 * bCr ~ .aki_stages[1],
Expand All @@ -27,15 +70,15 @@ aki.numeric <- function(SCr, bCr = NULL, na.rm = FALSE) {
return(aki_stages)
}


#' @rdname aki
#' @export
aki.ts <- function(ts_data) {
aki.ts <- function(SCr, UO, units = "umol/l", ...) {

}


#' @rdname aki
#' @export
aki.default <- function(x) {
factor(x, levels = .aki_stages)
aki.default <- function(data, SCr, bCr, units = list("SCr" = "umol/l"), na.rm = FALSE, ...) {
factor(data, levels = .aki_stages)
}
1 change: 1 addition & 0 deletions R/utils.R
@@ -0,0 +1 @@
# set_units(set_units(1:5, mg/dl) * set_units(2, mol/g), mol/l)
46 changes: 38 additions & 8 deletions man/aki.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

66 changes: 66 additions & 0 deletions tests/testthat/test-aki.R
@@ -1,3 +1,17 @@
test_that(".sCr2metric() conversion 88.4 umol/l to 1mg/dl is correct", {
expect_lte(
abs(.sCr2metric(units::set_units(88.4, "umol/l")) - units::set_units(1, "mg/dl")),
units::set_units(1e-4, "mg/dl")
)
})

test_that(".sCr2metric() conversion 353.6 umol/l to 4mg/dl is correct", {
expect_lte(
abs(.sCr2metric(units::set_units(353.6, "umol/l")) - units::set_units(4, "mg/dl")),
units::set_units(1e-4, "mg/dl")
)
})

test_that("aki() for numeric vector of SCr with no baseline", {
SCr <- seq(60, 200, by = 20)
aki_stages <- forcats::fct_c(
Expand Down Expand Up @@ -27,3 +41,55 @@ test_that("aki() for numeric vector of SCr with baseline", {
)
expect_equal(aki(SCr, bCr = 50), aki_stages)
})

test_that("aki() for vector of SCr in mg/dl with no baseline", {
SCr <- units::set_units(seq(1.5, 4.5, by = 0.5), "mg/dl")
aki_stages <- forcats::fct_c(
.aki_stages[length(.aki_stages)],
.aki_stages[length(.aki_stages)],
.aki_stages[1],
.aki_stages[2],
.aki_stages[2],
.aki_stages[3],
.aki_stages[3]
)
expect_equal(aki(SCr), aki_stages)
})

test_that("aki() for vector of SCr in mg/dl with baseline", {
SCr <- units::set_units(seq(2.0, 4.5, by = 0.5), "mg/dl")
bCr <- units::set_units(1.5, "mg/dl")
aki_stages <- forcats::fct_c(
.aki_stages[length(.aki_stages)],
.aki_stages[1],
.aki_stages[2],
.aki_stages[2],
.aki_stages[3],
.aki_stages[3]
)
expect_equal(aki(SCr, bCr), aki_stages)
})

data <- data.frame(
pt_id = c(rep("pt1", 11), rep("pt2", 13)),
dttm = c(
seq(
lubridate::as_datetime("2020-10-18 09:00:00", tz = "Australia/Melbourne"),
lubridate::as_datetime("2020-10-20 09:00:00", tz = "Australia/Melbourne"),
length.out = 11
),
seq(
lubridate::as_datetime("2020-10-18 10:00:00", tz = "Australia/Melbourne"),
lubridate::as_datetime("2020-10-29 10:00:00", tz = "Australia/Melbourne"),
length.out = 13
)
),
SCr = c(
units::set_units(seq(2.0, 4.5, by = 0.25), "mg/dl"),
units::set_units(seq(3.0, 4.2, by = 0.10), "mg/dl")
),
bCr = c(
rep(units::set_units(1.8, "mg/dl"), 11),
rep(units::set_units(3.0, "mg/dl"), 13)
)
)