1
0
mirror of https://github.com/msberends/AMR.git synced 2026-05-31 18:21:44 +02:00

Refactor R-classification logic using custom_breakpoints_set flag

Introduce custom_breakpoints_set <- !identical(reference_data, AMR::clinical_breakpoints)
at the top of as_sir_method() and replace all identical() calls inside that
function with this variable.

In the case_when_AMR interpretation blocks (MIC and disk), the R-classification
now has three explicit arms:
- !custom_breakpoints_set & EUCAST guideline -> open interval (> / <)
- !custom_breakpoints_set & CLSI guideline  -> closed interval (>= / <=)
- custom_breakpoints_set                    -> open interval (> / <), always,
  regardless of the guideline name in the custom data (e.g. "CLSI_custom"
  must not accidentally trigger CLSI convention)

https://claude.ai/code/session_01Q8KtFFGG9qrjAgLJBbxG2U
This commit is contained in:
Claude
2026-04-25 08:50:33 +00:00
parent 6ef7441d51
commit c43339d6ed

23
R/sir.R
View File

@@ -1286,6 +1286,7 @@ as_sir_method <- function(method_short,
} }
current_sir_interpretation_history <- NROW(AMR_env$sir_interpretation_history) current_sir_interpretation_history <- NROW(AMR_env$sir_interpretation_history)
custom_breakpoints_set <- !identical(reference_data, AMR::clinical_breakpoints)
if (isTRUE(info) && message_not_thrown_before("as.sir", "sir_interpretation_history")) { if (isTRUE(info) && message_not_thrown_before("as.sir", "sir_interpretation_history")) {
message_("Run {.help [{.fun sir_interpretation_history}](AMR::sir_interpretation_history)} afterwards to retrieve a logbook with all details of the breakpoint interpretations.\n\n") message_("Run {.help [{.fun sir_interpretation_history}](AMR::sir_interpretation_history)} afterwards to retrieve a logbook with all details of the breakpoint interpretations.\n\n")
@@ -1490,7 +1491,7 @@ as_sir_method <- function(method_short,
"\u00a0\u00a0", AMR_env$bullet_icon, " Interpreting ", method_long, ": ", ifelse(isTRUE(list(...)$is_data.frame), "column ", ""), "\u00a0\u00a0", AMR_env$bullet_icon, " Interpreting ", method_long, ": ", ifelse(isTRUE(list(...)$is_data.frame), "column ", ""),
ifelse(length(unique(agent_formatted)) == 1, unique(agent_formatted), paste0(vector_and(agent_formatted, quotes = FALSE, sort = FALSE))), ifelse(length(unique(agent_formatted)) == 1, unique(agent_formatted), paste0(vector_and(agent_formatted, quotes = FALSE, sort = FALSE))),
mo_var_found, mo_var_found,
ifelse(identical(reference_data, AMR::clinical_breakpoints), ifelse(!custom_breakpoints_set,
paste0(", ", vector_and(font_bold(guideline_coerced, collapse = NULL), quotes = FALSE)), paste0(", ", vector_and(font_bold(guideline_coerced, collapse = NULL), quotes = FALSE)),
"" ""
), ),
@@ -1507,7 +1508,7 @@ as_sir_method <- function(method_short,
method_coerced <- toupper(method) method_coerced <- toupper(method)
ab_coerced <- as.ab(ab, info = FALSE) ab_coerced <- as.ab(ab, info = FALSE)
if (identical(reference_data, AMR::clinical_breakpoints)) { if (!custom_breakpoints_set) {
breakpoints <- reference_data %pm>% breakpoints <- reference_data %pm>%
subset(guideline %in% guideline_coerced & method == method_coerced & ab %in% ab_coerced) subset(guideline %in% guideline_coerced & method == method_coerced & ab %in% ab_coerced)
if (any(ab_coerced == "AMX") && nrow(breakpoints[breakpoints$ab == "AMX", , drop = FALSE]) == 0) { if (any(ab_coerced == "AMX") && nrow(breakpoints[breakpoints$ab == "AMX", , drop = FALSE]) == 0) {
@@ -1691,7 +1692,7 @@ as_sir_method <- function(method_short,
# gather all available breakpoints for current MO # gather all available breakpoints for current MO
# TODO for VET09 do not filter out E. coli and such # TODO for VET09 do not filter out E. coli and such
# For custom reference_data: skip guideline filter when guideline_current is not in the data (#239) # For custom reference_data: skip guideline filter when guideline_current is not in the data (#239)
guideline_filter_current <- if (!identical(reference_data, AMR::clinical_breakpoints) && guideline_filter_current <- if (custom_breakpoints_set &&
!guideline_current %in% breakpoints$guideline) { !guideline_current %in% breakpoints$guideline) {
unique(breakpoints$guideline) unique(breakpoints$guideline)
} else { } else {
@@ -1990,9 +1991,11 @@ as_sir_method <- function(method_short,
# otherwise: the normal (uncapped or ignored) interpretation # otherwise: the normal (uncapped or ignored) interpretation
input_clean <= breakpoints_current$breakpoint_S ~ as.sir("S"), input_clean <= breakpoints_current$breakpoint_S ~ as.sir("S"),
# CLSI uses closed interval (>=); EUCAST and all custom guidelines use open interval (>) # standard data: EUCAST open interval (>), CLSI closed interval (>=)
guideline_current %like% "CLSI" & input_clean >= breakpoints_current$breakpoint_R ~ as.sir("R"), !custom_breakpoints_set & guideline_current %like% "EUCAST" & input_clean > breakpoints_current$breakpoint_R ~ as.sir("R"),
!guideline_current %like% "CLSI" & input_clean > breakpoints_current$breakpoint_R ~ as.sir("R"), !custom_breakpoints_set & guideline_current %like% "CLSI" & input_clean >= breakpoints_current$breakpoint_R ~ as.sir("R"),
# custom reference_data: always EUCAST open interval (>), regardless of guideline name
custom_breakpoints_set & input_clean > breakpoints_current$breakpoint_R ~ as.sir("R"),
# return "I" or "SDD" when breakpoints are in the middle # return "I" or "SDD" when breakpoints are in the middle
!is.na(breakpoints_current$breakpoint_S) & !is.na(breakpoints_current$breakpoint_R) & breakpoints_current$is_SDD == TRUE ~ as.sir("SDD"), !is.na(breakpoints_current$breakpoint_S) & !is.na(breakpoints_current$breakpoint_R) & breakpoints_current$is_SDD == TRUE ~ as.sir("SDD"),
@@ -2005,9 +2008,11 @@ as_sir_method <- function(method_short,
new_sir <- case_when_AMR( new_sir <- case_when_AMR(
is.na(input_clean) ~ NA_sir_, is.na(input_clean) ~ NA_sir_,
as.double(input_clean) >= as.double(breakpoints_current$breakpoint_S) ~ as.sir("S"), as.double(input_clean) >= as.double(breakpoints_current$breakpoint_S) ~ as.sir("S"),
# CLSI uses closed interval (<=); EUCAST and all custom guidelines use open interval (<) # standard data: EUCAST open interval (<), CLSI closed interval (<=)
guideline_current %like% "CLSI" & as.double(input_clean) <= as.double(breakpoints_current$breakpoint_R) ~ as.sir("R"), !custom_breakpoints_set & guideline_current %like% "EUCAST" & as.double(input_clean) < as.double(breakpoints_current$breakpoint_R) ~ as.sir("R"),
!guideline_current %like% "CLSI" & as.double(input_clean) < as.double(breakpoints_current$breakpoint_R) ~ as.sir("R"), !custom_breakpoints_set & guideline_current %like% "CLSI" & as.double(input_clean) <= as.double(breakpoints_current$breakpoint_R) ~ as.sir("R"),
# custom reference_data: always EUCAST open interval (<), regardless of guideline name
custom_breakpoints_set & as.double(input_clean) < as.double(breakpoints_current$breakpoint_R) ~ as.sir("R"),
# return "I" or "SDD" when breakpoints are in the middle # return "I" or "SDD" when breakpoints are in the middle
!is.na(breakpoints_current$breakpoint_S) & !is.na(breakpoints_current$breakpoint_R) & breakpoints_current$is_SDD == TRUE ~ as.sir("SDD"), !is.na(breakpoints_current$breakpoint_S) & !is.na(breakpoints_current$breakpoint_R) & breakpoints_current$is_SDD == TRUE ~ as.sir("SDD"),
!is.na(breakpoints_current$breakpoint_S) & !is.na(breakpoints_current$breakpoint_R) & breakpoints_current$is_SDD == FALSE ~ as.sir("I"), !is.na(breakpoints_current$breakpoint_S) & !is.na(breakpoints_current$breakpoint_R) & breakpoints_current$is_SDD == FALSE ~ as.sir("I"),