Make anaerobes more specific than a Gram stain in rank_index

Anaerobes now have rank_index 5.5 (5.6 for a blocking row), and a Gram stain stays at 6. They had the same rank, so the order of sites could make the Gram-negative row with site Parenteral (CLSI Table 2B-5) precede the anaerobe row without a site (CLSI Table 2J), e.g., for ceftriaxone in B. fragilis.

A rebuild changes rank_index in 884 rows and nothing else.
This commit is contained in:
dr. M.S. (Matthijs) Berends committed 2026-11-03 08:37:55 +01:00
1 parent e7077081b9
commit 81f5aaa7b8
16 files changed
+900 -890

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
Package: AMR
Version: 3.1.0.9015
Date: 2026-11-02
Date: 2026-11-03
Title: Antimicrobial Resistance Data Analysis
Description: Functions to simplify and standardise antimicrobial resistance (AMR)
data analysis and to work with microbial and antimicrobial properties by
+1 -1
View File
@@ -298,7 +298,7 @@
#' - `method`\cr Testing method, either `r vector_or(clinical_breakpoints$method, documentation = TRUE)`
#' - `site`\cr Body site for which the breakpoint must be applied, e.g. "Oral" or "Respiratory"
#' - `mo`\cr Microbial ID, see [as.mo()]
#' - `rank_index`\cr Taxonomic rank index of `mo`, used to choose the most specific breakpoint (the lowest index): 1 for subspecies and infraspecies, 2 for species, 2.5 for species groups (e.g., *Streptococcus* group A), 3 for genus, 4 for family, 5 for order, 6 for other groups (e.g., Gram-negative or anaerobic bacteria), and 7 for non-species related (PK-PD) breakpoints. Blocking rows (see *Details*) have the rank index of their organism + 0.1, e.g., 2.6 for a species group, so that a breakpoint for the same organism always takes precedence.
#' - `rank_index`\cr Taxonomic rank index of `mo`, used to choose the most specific breakpoint (the lowest index): 1 for subspecies and infraspecies, 2 for species, 2.5 for species groups (e.g., *Streptococcus* group A), 3 for genus, 4 for family, 5 for order, 5.5 for anaerobic bacteria, 6 for other groups (e.g., Gram-negative bacteria), and 7 for non-species related (PK-PD) breakpoints. Blocking rows (see *Details*) have the rank index of their organism + 0.1, e.g., 2.6 for a species group, so that a breakpoint for the same organism always takes precedence.
#' - `ab`\cr Antimicrobial code as used by this package, EARS-Net and WHONET, see [as.ab()]
#' - `ref_tbl`\cr Info about where the guideline rule can be found
#' - `disk_dose`\cr Dose of the used disk diffusion method
@@ -720,7 +720,8 @@ breakpoints_new <- breakpoints_new |>
mo_rank(mo, keep_synonyms = TRUE) == "genus" ~ 3,
mo_rank(mo, keep_synonyms = TRUE) == "family" ~ 4,
mo_rank(mo, keep_synonyms = TRUE) == "order" ~ 5,
mo != "UNKNOWN" ~ 6, # for B_ANAER, etc.
grepl("^B_ANAER", as.character(mo)) ~ 5.5, # anaerobes are more specific than a Gram stain
mo != "UNKNOWN" ~ 6, # for B_GRAMN, etc.
TRUE ~ 7
) +
# a breakpoint of the same organism always precedes its blocking row
@@ -2782,7 +2782,8 @@ breakpoints_eucast <- breakpoints_eucast |>
mutate(
rank_index = case_when(
mo == "UNKNOWN" ~ 7, # the PK-PD table, as for the WHONET-based rows
is.na(mo_rank(mo, keep_synonyms = TRUE)) ~ 6, # for B_GRAMN, B_ANAER, B_ANAER-NEG, etc.
grepl("^B_ANAER", as.character(mo)) ~ 5.5, # anaerobes are more specific than a Gram stain
is.na(mo_rank(mo, keep_synonyms = TRUE)) ~ 6, # for B_GRAMN, etc.
mo_rank(mo, keep_synonyms = TRUE) %like% "(infra|sub)" ~ 1,
mo_rank(mo, keep_synonyms = TRUE) == "species" ~ 2,
mo_rank(mo, keep_synonyms = TRUE) == "species group" ~ 2.5,
+1 -1
View File
@@ -1 +1 @@
56c3254d6c81a4b3b82d3dc345fdaa68
8ec8bf482dcbf91277066759fe4f498b
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large. Load diff
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -13,7 +13,7 @@ A \link[tibble:tibble]{tibble} with 48 382 observations and 15 variables:
\item \code{method}\cr Testing method, either \code{"DISK"} or \code{"MIC"}
\item \code{site}\cr Body site for which the breakpoint must be applied, e.g. "Oral" or "Respiratory"
\item \code{mo}\cr Microbial ID, see \code{\link[=as.mo]{as.mo()}}
\item \code{rank_index}\cr Taxonomic rank index of \code{mo}, used to choose the most specific breakpoint (the lowest index): 1 for subspecies and infraspecies, 2 for species, 2.5 for species groups (e.g., \emph{Streptococcus} group A), 3 for genus, 4 for family, 5 for order, 6 for other groups (e.g., Gram-negative or anaerobic bacteria), and 7 for non-species related (PK-PD) breakpoints. Blocking rows (see \emph{Details}) have the rank index of their organism + 0.1, e.g., 2.6 for a species group, so that a breakpoint for the same organism always takes precedence.
\item \code{rank_index}\cr Taxonomic rank index of \code{mo}, used to choose the most specific breakpoint (the lowest index): 1 for subspecies and infraspecies, 2 for species, 2.5 for species groups (e.g., \emph{Streptococcus} group A), 3 for genus, 4 for family, 5 for order, 5.5 for anaerobic bacteria, 6 for other groups (e.g., Gram-negative bacteria), and 7 for non-species related (PK-PD) breakpoints. Blocking rows (see \emph{Details}) have the rank index of their organism + 0.1, e.g., 2.6 for a species group, so that a breakpoint for the same organism always takes precedence.
\item \code{ab}\cr Antimicrobial code as used by this package, EARS-Net and WHONET, see \code{\link[=as.ab]{as.ab()}}
\item \code{ref_tbl}\cr Info about where the guideline rule can be found
\item \code{disk_dose}\cr Dose of the used disk diffusion method
+3
View File
@@ -756,6 +756,9 @@ test_that("clinical_breakpoints: consistent and unambiguous", {
expected <- c("subspecies" = 1, "species" = 2, "species group" = 2.5, "genus" = 3, "family" = 4, "order" = 5)[rank]
wrong <- which(!is.na(expected) & floor(cb$rank_index * 2) / 2 != expected & cb$rank_index != expected)
expect_true(length(wrong) == 0, info = paste("rank_index does not match the rank:", describe_mo(unique(cb$mo[wrong]))))
# anaerobes are more specific than a Gram stain, with or without the 0.1 of a blocking row
expect_true(all(cb$rank_index[grepl("^B_ANAER", cb$mo)] %in% c(5.5, 5.6)))
expect_true(all(cb$rank_index[cb$mo %in% c("B_GRAMN", "B_GRAMP")] %in% c(6, 6.1)))
})
test_that("antimicrobials: unique and well-formed", {
+5
View File
@@ -730,6 +730,11 @@ test_that("as.sir() takes the site of a breakpoint into account", {
expect_true(sir_site_rank("Intravenous, Meningitis") < sir_site_rank("Intravenous, Non-meningitis"))
expect_true(sir_site_rank("Intravenous, Non-meningitis") < sir_site_rank("Meningitis"))
# the order of sites does not make a Gram stain precede the more specific anaerobes: CLSI Table 2J, not Table 2B-5
expect_identical(sir(as.mic(16), "Bacteroides fragilis", "CRO", guideline = "CLSI 2022"), "S")
# and it does make a meningitis breakpoint precede a non-meningitis breakpoint of another taxon of the same rank
expect_identical(sir(as.mic(0.25), "Streptococcus agalactiae", "PEN", guideline = "EUCAST 2024"), "R")
# "other" in as.sir(): takes the breakpoint for other infections, or without a site
expect_identical(sir(as.mic(0.25), "Streptococcus pneumoniae", "PEN", site = "other", guideline = "EUCAST 2012"), "I")
expect_identical(sir(as.mic(0.25), "Streptococcus pneumoniae", "PEN", site = "meningitis", guideline = "EUCAST 2012"), "R")