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

Sic bugfixes #10

Merged
merged 41 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from 40 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
0d7e464
define SIC data structure
prockenschaub Apr 26, 2023
9ffcb4d
add SIC to auto attach
prockenschaub Apr 26, 2023
2884e3f
add SIC loading helpers
prockenschaub Apr 26, 2023
2b39787
add callback hooks to postprocess tbls on import
prockenschaub May 11, 2023
d459959
add callback to deserialise sicdb data_float_h
prockenschaub May 11, 2023
32b8f60
add missing tbl_callback function
prockenschaub May 11, 2023
6afe44c
add sic_itm inspired by hrd_itm
prockenschaub May 11, 2023
bc41f88
adjust data_float_h config to recent changes
prockenschaub May 11, 2023
b53c592
add hr and crea as examples for sicdb
prockenschaub May 11, 2023
3ca5b04
add sex and death concepts for sic
prockenschaub Jul 26, 2023
9396da5
add vitals, labs, height, and weight concepts for sic
prockenschaub Jul 26, 2023
e84ea7d
add age and los_icu concepts
prockenschaub Jul 26, 2023
b9350a1
add most medication concepts for sic
prockenschaub Jul 26, 2023
5419ab4
fix preproc for data_float_h
prockenschaub Jul 26, 2023
078149e
add OMR to miiv
dplecko Mar 17, 2023
e5be7e8
add miiv omr
dplecko Apr 11, 2023
c8d0c9b
load_concepts() concepts arg doc fix
dplecko May 1, 2023
b1e2aed
load_concepts.integer() src NULL fix
dplecko May 1, 2023
9c3481f
Fix sic config
manuelburger Mar 20, 2024
d5d4c07
Properly support full rawdata found in sic
manuelburger Mar 20, 2024
31d48f7
Remove print
manuelburger Mar 20, 2024
eb41aaa
Add utility functions proposed by `prockenschaub` here: https://githu…
manuelburger Mar 20, 2024
3621a42
Merge branch 'sicdb' of github.com:prockenschaub/ricu-package into si…
manuelburger Mar 25, 2024
e4c930a
Fix configs for `sic` based on `prockenschaub`
manuelburger Mar 25, 2024
6ef9b50
Merge branch 'main' of github.com:ratschlab/ricu into sic-bugfixes
manuelburger Mar 25, 2024
ee48363
Fix `sic` configs based on https://github.com/prockenschaub/ricu-pack…
manuelburger Mar 25, 2024
c2b8c49
Remove prints and use ricu msg
manuelburger Mar 25, 2024
e5061d4
Remove redundant `report_probolems`
manuelburger Mar 25, 2024
2c8d763
Add prints and tempdir arg
manuelburger Mar 25, 2024
71672bf
Merge branch 'sic-bugfixes' of github.com:ratschlab/ricu into sic-bug…
manuelburger Mar 25, 2024
14a1403
Cleanup prints
manuelburger Mar 25, 2024
d96d9fe
Fix blood_gas config
manuelburger Mar 25, 2024
fa37f63
Fix sic table config
manuelburger Mar 25, 2024
9f152c3
Use finer resolution rawdata where available
manuelburger Mar 25, 2024
74a66d9
Pass tbl callback correctly
manuelburger Mar 25, 2024
84ec51f
Fix missing callback application
manuelburger Mar 25, 2024
99529cd
Apply callback before split_write
manuelburger Mar 25, 2024
f54afad
Config updates:
manuelburger Mar 26, 2024
ad6b07e
Fix configs
manuelburger Mar 26, 2024
640d4d2
Fix callback
manuelburger Mar 26, 2024
9ebaf7f
Use `apply_map` for `sic` `sex`
manuelburger Mar 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 39 additions & 7 deletions R/callback-itm.R
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,16 @@ mimic_age <- function(x) {

eicu_age <- function(x) as.numeric(ifelse(x == "> 89", 90, x))

sic_sex <- function(x) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this different from apply_map(735="Female", 735="Male"))?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jup, definitely the same and simpler. That came from merging PR code from eth-mds. Fixed it.

ifelse(
x == 735,
"Male",
ifelse(x == 736,
"Female",
NA_character_
))
}

hirid_death <- function(x, val_var, sub_var, env, ...) {

dis <- "discharge_status"
Expand Down Expand Up @@ -629,18 +639,24 @@ aumc_rate_units <- function(mcg_to_units) {
}

sic_dur <- function (x, val_var, stop_var, grp_var = NULL, ...) {

calc_dur(x, val_var, index_var(x), stop_var, grp_var)
}

sic_rate_kg <- function (x, val_var, stop_var, env, ...) {

res <- add_weight(x, env, "weight")
wgh_var <- "weight"
res[, c(val_var) := get(val_var) * 10^3 / get(wgh_var)]
expand(res, index_var(x), stop_var, keep_vars = c(id_vars(x), val_var))
sic_rate_kg <- function(x, val_var, unit_var, stop_var, env, ...) {

g_to_mcg <- convert_unit(binary_op(`*`, 1000000), "mcg", "g")

res <- g_to_mcg(x, val_var, unit_var)
res <- add_weight(res, env, "weight")

res <- res[, c(val_var) := get(val_var) / get("weight")]
res <- res[, c(unit_var) := paste(get(unit_var), "min", sep = "/kg/")]

expand(res, index_var(x), stop_var,
keep_vars = c(id_vars(x), val_var, unit_var))
}


eicu_duration <- function(gap_length) {

assert_that(is_interval(gap_length), is_scalar(gap_length))
Expand All @@ -662,6 +678,15 @@ aumc_dur <- function(x, val_var, stop_var, grp_var, ...) {
calc_dur(x, val_var, index_var(x), stop_var, grp_var)
}

default_duration <- function(x, val_var, stop_var, grp_var, ...) {
calc_dur(x, val_var, index_var(x), stop_var, grp_var)
}

no_duration <- function(x, val_var, grp_var, ...) {
calc_dur(x, val_var, index_var(x), index_var(x), grp_var)
}


#' Used for determining vasopressor durations, `calc_dur()` will calculate
#' durations by taking either per ID or per combination of ID and `grp_var`
#' the minimum for `min_var` and the maximum of `max_var` and returning the
Expand Down Expand Up @@ -778,6 +803,13 @@ aumc_death <- function(x, val_var, ...) {
x
}

sic_death <- function(x, val_var, adm_time, ...) {
idx <- index_var(x)

x <- x[, c(val_var) := is_true(get(idx) - (get(adm_time) + secs(get(val_var))) < hours(72L))]
x
}

aumc_bxs <- function(x, val_var, dir_var, ...) {
x <- x[get(dir_var) == "-", c(val_var) := -1L * get(val_var)]
x
Expand Down
36 changes: 36 additions & 0 deletions R/callback-tbl.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

sic_data_float_h <- function(dat, ...) {

hexstring_to_float <- function(x) {
if (is.na(x)) {
return(NA_real_)
}
hexstring <- substring(x, seq(1, 482, 2), seq(2, 482, 2))
bytes <- as.raw(strtoi(hexstring[-1], base = 16))
floats <- readBin(bytes, numeric(), length(bytes) %/% 4, 4, endian = "little")
ifelse(floats == 0, NA_real_, floats)
}

setDT(dat)

# TODO: remove hard coding of rawdata and derive from JSON config
dat[, c("rawdata") := lapply(get("rawdata"), hexstring_to_float)]
dat <- dat[, .(
Offset = Offset + 60 * (0:(sapply(rawdata, length)-1)),
Val = Val,
cnt = cnt,
rawdata = unlist(rawdata),
rawdata_present = !is.na(rawdata)
),
by = .(id, CaseID, DataID)
]

# Fix measurements that only have one value
dat[rawdata_present == FALSE, rawdata := Val]
dat[, rawdata_present := NULL]

return(dat)

}


63 changes: 63 additions & 0 deletions R/concept-utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,30 @@ get_hirid_ids <- function(x, ids) {
load_id("variables", x, .data$id %in% .env$ids, cols = "unit", id_var = "id")
}

#' @rdname data_items
#' @export
init_itm.sic_itm <- function(x, table, sub_var, ids,
callback = "identity_callback", ...) {

assert_that(is.string(table), has_length(ids),
is.character(ids) || is_intish(ids))

x[["table"]] <- table

units <- get_sic_ids(x, ids)
units <- rename_cols(rm_na(units), sub_var, "referenceglobalid")

todo <- c("ids", "units")
x[todo] <- mget(todo)

complete_tbl_itm(x, callback, sub_var, ...)
}

get_sic_ids <- function(x, ids) {
load_id("d_references", x, .data$referenceglobalid %in% .env$ids, cols = "referenceunit", id_var = "referenceglobalid")
}


#' @param unit_val String valued unit to be used in case no `unit_var` is
#' available for the given table
#'
Expand Down Expand Up @@ -330,6 +354,10 @@ prepare_query.sel_itm <- prep_sel
#' @export
prepare_query.hrd_itm <- prep_sel

#' @keywords internal
#' @export
prepare_query.sic_itm <- prep_sel

#' @keywords internal
#' @export
prepare_query.rgx_itm <- function(x) {
Expand Down Expand Up @@ -546,6 +574,28 @@ do_callback.hrd_itm <- function(x, ...) {
NextMethod()
}

#' @keywords internal
#' @export
do_callback.sic_itm <- function(x, ...) {
# TODO: generalise and combine with do_callback.hrd_itm
if (is.null(get_itm_var(x, "unit_var"))) {
x <- try_add_vars(x, unit_var = "referenceunit")
}

NextMethod()
}

#' @keywords internal
#' @export
do_callback.sic_itm <- function(x, ...) {
# TODO: generalise and combine with do_callback.hrd_itm
if (is.null(get_itm_var(x, "unit_var"))) {
x <- try_add_vars(x, unit_var = "referenceunit")
}

NextMethod()
}

#' @keywords internal
#' @export
do_callback.col_itm <- function(x, ...) {
Expand Down Expand Up @@ -604,6 +654,19 @@ do_itm_load.hrd_itm <- function(x, id_type = "icustay", interval = hours(1L)) {
res
}

#' @export
do_itm_load.sic_itm <- function(x, id_type = "icustay", interval = hours(1L)) {

res <- NextMethod()

if (is.null(get_itm_var(x, "unit_var"))) {
unt <- x[["units"]]
res <- merge(res, unt, by = get_itm_var(x, "sub_var"), all.x = TRUE)
}

res
}

#' @export
do_itm_load.col_itm <- function(x, id_type = "icustay", interval = hours(1L)) {

Expand Down
28 changes: 28 additions & 0 deletions R/config-utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,34 @@ partition_col <- function(x, orig_names = FALSE) {
col
}

tbl_callback <- function(x){
x <- as_tbl_cfg(x)
assert_that(length(x) == 1L)

if (!("callback" %in% vctrs::fields(x))) {
return(identity_callback)
}

callback_field <- vctrs::field(x, "callback")
if (is.character(callback_field)) {
msg_ricu(paste("[tbl_callback] Using callback function: ", callback_field))
return(str_to_fun(callback_field))
}

if (!is.null(callback_field) && !is.list(callback_field)) {
return(identity_callback)
}

callback_value <- callback_field[[1]]
if (is.character(callback_value)) {
msg_ricu(paste("[tbl_callback] Using callback function: ", callback_value))
return(str_to_fun(callback_value))
}

return(identity_callback)
}


#' @export
n_tick.tbl_cfg <- function(x) {

Expand Down
1 change: 0 additions & 1 deletion R/data-load.R
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,6 @@ load_difftime.picdb_tbl <- function(x, rows, cols = colnames(x),
time_vars = ricu::time_vars(x), ...) {

warn_dots(...)

load_mihi(x, {{ rows }}, cols, id_hint, time_vars)
}

Expand Down
57 changes: 39 additions & 18 deletions R/data-utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,28 @@ id_orig_helper.miiv_env <- function(x, id) {
as_id_tbl(res, id, by_ref = TRUE)
}

#' @rdname data_utils
#' @export
id_orig_helper.sic_env <- function(x, id) {

if (!identical(id, "patientid")) {
return(NextMethod())
}

cfg <- as_id_cfg(x)[id == id_var_opts(x)]

assert_that(length(cfg) == 1L)

sta <- field(cfg, "start")
age <- "admissionyear"

res <- as_src_tbl(x, field(cfg, "table"))
res <- res[, c(id, sta, age)]
res <- res[, c(sta, age) := shift_year(get(sta), get(age))]

as_id_tbl(res, id, by_ref = TRUE)
}

#' @export
id_orig_helper.default <- function(x, ...) stop_generic(x, .Generic)

Expand Down Expand Up @@ -228,33 +250,32 @@ id_win_helper.eicu_env <- function(x) {
order_rename(res, ids, sta, end)
}

#' @rdname data_utils
#' @export
id_win_helper.sic_env <- function(x) {

sec_as_mins <- function(x) min_as_mins(as.integer(x / 60))


#' @rdname data_utils
#' @export
id_win_helper.sic_env <- function(x) {
cfg <- sort(as_id_cfg(x), decreasing = TRUE)

ids <- field(cfg, "id")
sta <- c(unique(field(cfg, "start")), "HospAdmTime")
sta <- field(cfg, "start")
end <- field(cfg, "end")

tbl <- as_src_tbl(x, unique(field(cfg, "table")))

mis <- setdiff(sta, colnames(tbl))

res <- load_src(tbl, cols = c(ids, intersect(sta, colnames(tbl)), end))

if (length(mis) > 0L) {
res[, c(mis) := 0L]
}

res <- res[, c(sta, end) := lapply(.SD, sec_as_mins), .SDcols = c(sta, end)]

assert_that(length(mis) == 1L)
res[, firstadmission := 0L]

res <- res[, c(sta, end) := lapply(.SD, s_as_mins), .SDcols = c(sta, end)]
res[, timeofstay := offsetafterfirstadmission + timeofstay]

res <- setcolorder(res, c(ids, sta, end))
res <- rename_cols(res, c(ids, paste0(ids, "_start"),
paste0(ids, "_end")), by_ref = TRUE)

as_id_tbl(res, ids[2L], by_ref = TRUE)
}

Expand Down
Loading
Loading