From aa462e0ad6911cf14cc12ab23d68545c4ada6e97 Mon Sep 17 00:00:00 2001 From: Matthijs Berends Date: Sat, 10 Oct 2026 11:46:17 +0200 Subject: [PATCH] (v3.0.1.9110) Link all code TODO markers to issues (#317, #318, #319), and stop counting the WHONET code "XXX" in the TODO tracker --- .github/workflows/publish-to-pypi.yml | 2 +- .github/workflows/todo-tracker.yml | 3 +- DESCRIPTION | 2 +- NEWS.md | 2 +- R/sir.R | 30 +++++++++---------- .../reproduction_of_clinical_breakpoints.R | 2 +- .../reproduction_of_microorganisms.R | 2 +- 7 files changed, 22 insertions(+), 21 deletions(-) diff --git a/.github/workflows/publish-to-pypi.yml b/.github/workflows/publish-to-pypi.yml index 1042e5ec2..71c46511c 100644 --- a/.github/workflows/publish-to-pypi.yml +++ b/.github/workflows/publish-to-pypi.yml @@ -78,7 +78,7 @@ jobs: cd PythonPackage/AMR python -m twine upload --repository-url https://test.pypi.org/legacy/ dist/* - # TODO - Support Miniconda and Anaconda too + # TODO #319: support Miniconda and Anaconda too # - name: Set up Miniconda # continue-on-error: true # uses: conda-incubator/setup-miniconda@v2 diff --git a/.github/workflows/todo-tracker.yml b/.github/workflows/todo-tracker.yml index 3c7d750e0..f5664c4ed 100644 --- a/.github/workflows/todo-tracker.yml +++ b/.github/workflows/todo-tracker.yml @@ -75,7 +75,8 @@ jobs: --include='*.yml' --include='*.md' --include='*.css' \ --include='*.js' \ --exclude='todo-tracker.yml' --exclude='todo.md' \ - -E '\b(TODO|FIXME|HACK|XXX)\b' . > /tmp/raw.txt || true + -E '\b(TODO|FIXME|HACK|XXX)\b' . \ + | grep -vE '"XXX"' > /tmp/raw.txt || true if [ ! -s /tmp/raw.txt ]; then echo -e "## \`TODO\` Report\n\n**Last Updated: ${LAST_UPDATED}**\n\nNo markers found." > todo.md diff --git a/DESCRIPTION b/DESCRIPTION index 12a7fa0a8..d4b92b4e3 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,5 +1,5 @@ Package: AMR -Version: 3.0.1.9109 +Version: 3.0.1.9110 Date: 2026-10-10 Title: Antimicrobial Resistance Data Analysis Description: Functions to simplify and standardise antimicrobial resistance (AMR) diff --git a/NEWS.md b/NEWS.md index 1d1785064..b453b1cc4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# AMR 3.0.1.9109 +# AMR 3.0.1.9110 Planned as v3.1.0, mid October 2026. diff --git a/R/sir.R b/R/sir.R index 07c2175b4..13b1fdfe0 100755 --- a/R/sir.R +++ b/R/sir.R @@ -153,7 +153,7 @@ VALID_SIR_LEVELS <- c("S", "SDD", "I", "R", "NI", "WT", "NWT", "NS") #' options(AMR_breakpoint_type = "animal") #' ``` #' -###### TODO #187 When applying veterinary breakpoints (by setting `host` or by setting `breakpoint_type = "animal"`), the [CLSI VET09 guideline](https://clsi.org/standards/products/veterinary-medicine/documents/vet09/) will be applied to cope with missing animal species-specific breakpoints. +###### TODO #317: When applying veterinary breakpoints (by setting `host` or by setting `breakpoint_type = "animal"`), the [CLSI VET09 guideline](https://clsi.org/standards/products/veterinary-medicine/documents/vet09/) will be applied to cope with missing animal species-specific breakpoints. #' #' ### After Interpretation #' @@ -182,7 +182,7 @@ VALID_SIR_LEVELS <- c("S", "SDD", "I", "R", "NI", "WT", "NWT", "NS") #' - **CLSI M39: Analysis and Presentation of Cumulative Antimicrobial Susceptibility Test Data**, `r min(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, guideline %like% "CLSI")$guideline)))`-`r max(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, guideline %like% "CLSI")$guideline)))`, *Clinical and Laboratory Standards Institute* (CLSI). . #' - **CLSI M100: Performance Standard for Antimicrobial Susceptibility Testing**, `r min(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, guideline %like% "CLSI" & type != "animal")$guideline)))`-`r max(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, guideline %like% "CLSI" & type != "animal")$guideline)))`, *Clinical and Laboratory Standards Institute* (CLSI). . #' - **CLSI VET01: Performance Standards for Antimicrobial Disk and Dilution Susceptibility Tests for Bacteria Isolated From Animals**, `r min(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, guideline %like% "CLSI" & type == "animal")$guideline)))`-`r max(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, guideline %like% "CLSI" & type == "animal")$guideline)))`, *Clinical and Laboratory Standards Institute* (CLSI). . -###### TODO - **CLSI VET09: Understanding Susceptibility Test Data as a Component of Antimicrobial Stewardship in Veterinary Settings**, `r min(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, guideline %like% "CLSI" & type == "animal")$guideline)))`-`r max(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, guideline %like% "CLSI" & type == "animal")$guideline)))`, *Clinical and Laboratory Standards Institute* (CLSI). . +###### TODO #317: - **CLSI VET09: Understanding Susceptibility Test Data as a Component of Antimicrobial Stewardship in Veterinary Settings**, `r min(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, guideline %like% "CLSI" & type == "animal")$guideline)))`-`r max(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, guideline %like% "CLSI" & type == "animal")$guideline)))`, *Clinical and Laboratory Standards Institute* (CLSI). . #' - **EUCAST Breakpoint tables for interpretation of MICs and zone diameters**, `r min(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, guideline %like% "EUCAST")$guideline)))`-`r max(as.integer(gsub("[^0-9]", "", subset(AMR::clinical_breakpoints, guideline %like% "EUCAST")$guideline)))`, *European Committee on Antimicrobial Susceptibility Testing* (EUCAST). . #' - **WHONET** as a source for machine-reading the clinical breakpoints ([read more here](https://amr-for-r.org/reference/clinical_breakpoints.html#imported-from-whonet)), 1989-`r max(as.integer(gsub("[^0-9]", "", AMR::clinical_breakpoints$guideline)))`, *WHO Collaborating Centre for Surveillance of Antimicrobial Resistance*. . #' @@ -409,7 +409,7 @@ as_sir_structure <- function(x, levels = VALID_SIR_LEVELS, ordered = TRUE ), - # TODO for #170 + # TODO #170: store interpretation details as attributes # guideline = guideline, # mo = mo, # ab = ab, @@ -1320,7 +1320,7 @@ as_sir_method <- function(method_short, warning_("The following animal host(s) could not be coerced: ", vector_and(host.bak[is.na(host) & !is.na(host.bak)]), immediate = TRUE) message_(as_note = FALSE) # new line } - # TODO add a switch to turn this off? In interactive sessions perhaps ask the user. Default should be On. + # TODO #317: add a switch to turn this message off (in interactive sessions perhaps ask the user), default on # if (breakpoint_type == "animal" && isTRUE(info) && message_not_thrown_before("as.sir", "host_missing_breakpoints")) { # if (guideline_coerced %like% "CLSI") { # message_("Please note that in the absence of specific veterinary breakpoints for certain animal hosts, the CLSI guideline VET09 will be applied where possible.\n\n") @@ -1404,7 +1404,7 @@ as_sir_method <- function(method_short, ) } } - # TODO set uti to specimen column here + # TODO #318: derive uti from the specimen column here if (length(ab) == 1 && ab %like% paste0("as.", method_short)) { @@ -1632,8 +1632,8 @@ as_sir_method <- function(method_short, new_sir <- rep(NA_sir_, length(rows)) # find different mo properties, as fast as possible - # TODO in case of VET09, we need to keep E. coli, also when users have Proteus in their data set - # TODO look up which species, at least E. coli - also Staph or Strep? + # TODO #317: for VET09, keep E. coli, also when users have Proteus in their data set + # TODO #317: look up which species, at least E. coli, perhaps also Staph or Strep mo_current_genus <- AMR_env$MO_lookup$mo[match(AMR_env$MO_lookup$genus[match(mo_current, AMR_env$MO_lookup$mo)], AMR_env$MO_lookup$fullname)] mo_current_family <- AMR_env$MO_lookup$mo[match(AMR_env$MO_lookup$family[match(mo_current, AMR_env$MO_lookup$mo)], AMR_env$MO_lookup$fullname)] mo_current_order <- AMR_env$MO_lookup$mo[match(AMR_env$MO_lookup$order[match(mo_current, AMR_env$MO_lookup$mo)], AMR_env$MO_lookup$fullname)] @@ -1671,7 +1671,7 @@ as_sir_method <- function(method_short, ) # gather all available breakpoints for current MO - # TODO for VET09 do not filter out E. coli and such + # TODO #317: 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) guideline_filter_current <- if (custom_breakpoints_set && !guideline_current %in% breakpoints$guideline) { @@ -1700,12 +1700,12 @@ as_sir_method <- function(method_short, } ## fall-back methods for veterinary guidelines ---- - ## TODO actually implement this well + ## TODO #317: properly implement this if (FALSE) { # if (breakpoint_type == "animal" && !host_current %in% breakpoints_current$host) { if (guideline_coerced %like% "CLSI") { # VET09 says that staph/strep/enterococcus BP can be extrapolated to all Gr+ cocci except for intrinsic resistance, so take all Gr+ cocci: - gram_plus_cocci_vet09 <- microorganisms$mo[microorganisms$genus %in% c("Staphylococcus", "Streptococcus", "Peptostreptococcus", "Aerococcus", "Micrococcus") & microorganisms$rank == "genus"] # TODO should probably include genera that were either of these before + gram_plus_cocci_vet09 <- microorganisms$mo[microorganisms$genus %in% c("Staphylococcus", "Streptococcus", "Peptostreptococcus", "Aerococcus", "Micrococcus") & microorganisms$rank == "genus"] # TODO #317: should probably include genera formerly part of these # HUMAN SUBSTITUTES if (ab_current == "AZM" && mo_current_genus %in% gram_plus_cocci_vet09 && host_current %in% c("dogs", "cats", "horse")) { @@ -1754,7 +1754,7 @@ as_sir_method <- function(method_short, notes_current <- c(notes_current, paste0("Using ", font_bold("human"), " breakpoints for ", ab_formatted, " based on CLSI VET09.")) } else if (host_current %in% c("dogs", "cats") && (mo_current_genus %in% c("B_AMYCS", "B_NOCRD", "B_CMPYL", "B_CRYNB", "B_ENTRC", "B_MYCBC", "B_PSDMN", "B_AERMN") | mo_current_class == "B_[CLS]_BTPRTBCT" | mo_current == "B_LISTR_MNCY")) { # dog breakpoints if no canine/feline - # TODO do we still have dogs breakpoints at this point??? + # TODO #317: check whether dog breakpoints are still available at this point breakpoints_current <- breakpoints_current %pm>% subset(host == "human") # WRONG notes_current <- c(notes_current, paste0("Using ", font_bold("human"), " breakpoints for ", mo_formatted, " based on CLSI VET09.")) } else { @@ -2186,7 +2186,7 @@ freq.sir <- function(x, ...) { # this prevents the requirement for putting the dependency in Imports: #' @rawNamespace if(getRversion() >= "3.0.0") S3method(skimr::get_skimmers, sir) get_skimmers.sir <- function(column) { - # TODO #170 add here in AMR 3.1.0 details about guideline + # TODO #170: add details about guideline here skimr::sfl( skim_type = "sir", # guideline = function(x) "EUCAST 2026", # or "Multiple" @@ -2207,7 +2207,7 @@ get_skimmers.sir <- function(column) { print.sir <- function(x, ...) { x_name <- deparse(substitute(x)) cat(format_inline_("Class {.cls sir}\n")) - # TODO for #170 + # TODO #170: print interpretation details from attributes # if (!is.null(attributes(x)$guideline) && !all(is.na(attributes(x)$guideline))) { # cat(font_blue(word_wrap("These values were interpreted using ", # font_bold(vector_and(attributes(x)$guideline, quotes = FALSE)), @@ -2299,7 +2299,7 @@ summary.sir <- function(object, ...) { c.sir <- function(...) { lst <- list(...) - # TODO for #170 + # TODO #170: retrieve attributes of all elements # guideline <- vapply(FUN.VALUE = character(1), lst, function(x) attributes(x)$guideline %||% NA_character_) # mo <- vapply(FUN.VALUE = character(1), lst, function(x) attributes(x)$mo %||% NA_character_) # ab <- vapply(FUN.VALUE = character(1), lst, function(x) attributes(x)$ab %||% NA_character_) @@ -2309,7 +2309,7 @@ c.sir <- function(...) { out <- as.sir(unlist(lapply(list(...), as.character))) - # TODO for #170 + # TODO #170: restore attributes on the combined result # if (!all(is.na(guideline))) { # attributes(out)$guideline <- guideline # attributes(out)$mo <- mo diff --git a/data-raw/_reproduction_scripts/reproduction_of_clinical_breakpoints.R b/data-raw/_reproduction_scripts/reproduction_of_clinical_breakpoints.R index 71d7c8611..a7e2acef2 100644 --- a/data-raw/_reproduction_scripts/reproduction_of_clinical_breakpoints.R +++ b/data-raw/_reproduction_scripts/reproduction_of_clinical_breakpoints.R @@ -161,7 +161,7 @@ organisms <- organisms |> arrange(code, group) |> select(-group) |> distinct() -# no XXX +# remove WHONET placeholder organism code organisms <- organisms |> filter(code != "XXX") # 2023-07-08 SGM is also Strep gamma in WHONET, must only be Slowly-growing Mycobacterium diff --git a/data-raw/_reproduction_scripts/reproduction_of_microorganisms.R b/data-raw/_reproduction_scripts/reproduction_of_microorganisms.R index 06d7cbe22..3f1f4ed3f 100644 --- a/data-raw/_reproduction_scripts/reproduction_of_microorganisms.R +++ b/data-raw/_reproduction_scripts/reproduction_of_microorganisms.R @@ -1981,7 +1981,7 @@ current_gbif <- taxonomy_gbif.bak %>% taxonomy <- add_missing_parents(taxonomy, current_gbif) -# TODO perhaps only for 2026: remove old kingdoms +# remove the old kingdoms Bacteria and Archaea, these are domains taxonomy <- taxonomy %>% filter(!(rank == "kingdom" & fullname %in% c("Bacteria", "Archaea")))