1
0
mirror of https://github.com/msberends/AMR.git synced 2026-04-28 09:03:51 +02:00
Files
AMR/NEWS.md
Matthijs Berends 19157ce718 Fix parallel computing in as.sir.data.frame (#276)
* Fix parallel computing in as.sir.data.frame

Six bugs in parallel = TRUE mode:

1. PSOCK workers (Windows / R < 4.0) never had AMR loaded, so every
   exported/AMR function call failed. Added clusterEvalQ(cl, library(AMR))
   with a graceful fallback to sequential when the package cannot be loaded
   (e.g. dev-only load_all() environments).

2. clusterExport'd AMR_env was a frozen serialised copy; as.sir() on the
   worker wrote to AMR:::AMR_env while run_as_sir_column read from the stale
   copy, so the captured log was always wrong. Fixed by resolving AMR_env
   dynamically via get("AMR_env", envir = asNamespace("AMR")) inside the
   worker function, and removing AMR_env from clusterExport.

3. In the fork-based (mclapply) path each worker inherited the parent's full
   sir_interpretation_history. Capturing the whole log then combining across
   workers duplicated every pre-existing entry. Fixed by recording the log
   row count before the as.sir() call and slicing only the new rows
   afterwards.

4. run_as_sir_column used non-exported internals (%pm>%, pm_pull,
   as.sir.default) that are inaccessible on PSOCK workers after library(AMR).
   Replaced pipe chains with direct as.mic(as.character(x[, col, drop=TRUE]))
   and as.disk(...) calls, and changed as.sir.default() to as.sir() which
   dispatches correctly via S3.

5. With info = TRUE, worker forks printed per-column progress messages
   simultaneously, producing garbled interleaved console output. Per-column
   messages are now suppressed inside workers (effective_info = FALSE) while
   the outer "Running in parallel" / "DONE" messages still appear.

6. Malformed Unicode escape \u00a (3 hex digits) in the "DONE" banner was
   parsed by R as U+00AD (soft hyphen) + "ONE"; corrected to  .

https://claude.ai/code/session_012DXCXbZUC54Zij1z9bFiHR

* Add parallel computing tests to test-sir.R

Eight targeted tests verify correctness of the parallel as.sir() path:
identical SIR output vs sequential, matching log row counts, no
pre-existing history duplication, reproducibility across runs, results
consistency across max_cores values, single-column fallback, and no
per-column worker messages leaking when info = TRUE. All pass when only
1 core is available (parallel silently falls back to sequential).

https://claude.ai/code/session_012DXCXbZUC54Zij1z9bFiHR

* Fix as.sir() data.frame: preserve already-<sir> columns, exclude metadata

Issue #278: two related bugs in the column-detection / type-assignment pipeline.

Bug 1 – already-<sir> columns deleted on re-run
  Line 886 excluded already-sir columns from the type assignment (they
  stayed type "") causing the result loop to do x[,col] <- NULL, deleting
  them.  Fix: drop the !is.sir() guard so all untyped columns fall through
  to type "sir" and are re-processed correctly.

Bug 2 – metadata columns treated as antibiotics
  as.ab("patient") -> OXY, as.ab("ward") -> PRU.  The column detector
  accepted any column whose name matched an antibiotic code, regardless of
  content.  Fix: for name-matched columns that do not already carry an AMR
  class, also verify content looks like AMR data (all_valid_mics, all-
  numeric, or any SIR-like string).  all_valid_disks() is intentionally
  avoided here because it strips letters from strings (as.disk("Pt_1")==1).

Also adds tools/benchmark_parallel.R: a standalone script that times
sequential vs parallel as.sir() across n=20/200/2000/20000 rows and
saves a ggplot2 PNG to tools/benchmark_parallel.png.

https://claude.ai/code/session_012DXCXbZUC54Zij1z9bFiHR

* Update benchmark: two-panel script with warm-up and column-count sweep

Previous single-panel benchmark was misleading: the first sequential run
paid one-time cache-warm-up cost (skewing n=20), and only 6 columns were
used so only 6 cores were ever active on a 16-core machine.

New two-panel design:
  Left  – vary rows with 16 fixed AB columns (shows memory-bandwidth
          saturation for large n)
  Right – vary columns with fixed rows (shows the real speedup profile:
          parallel wins when n_cols >> 1)

Also adds a warm-up pass before measurements to eliminate first-call bias.

https://claude.ai/code/session_012DXCXbZUC54Zij1z9bFiHR

* Optimise parallel as.sir(): row-batch mode when n_cols < n_cores

Previously parallel dispatch only parallelised by column, so a 6-column
dataset on a 16-core machine used at most 6 cores with the other 10 idle.
For large n this also caused memory-bandwidth saturation (each worker did
a full n-row scan of clinical_breakpoints simultaneously).

New row-batch mode (fork path, R >= 4.0, non-Windows):
  pieces_per_col = ceil(n_cores / n_cols)
  Jobs = n_cols × pieces_per_col  (≈ n_cores jobs total)
  Each job: one column × one row slice

Benefits:
  - All cores stay busy regardless of column count
  - Per-worker memory footprint shrinks by pieces_per_col ×
  - Breakpoints lookup cache pressure reduced per worker

PSOCK path (Windows / R < 4.0) is unchanged: per-job serialisation
overhead makes row batching unprofitable there.

run_as_sir_column() gains an optional `rows` parameter (NULL = all rows,
backward-compatible). Results are reassembled via as.sir(c(as.character(.)))
which is safe for already-clean SIR values.

https://claude.ai/code/session_012DXCXbZUC54Zij1z9bFiHR

* Fix info=FALSE ignored when no breakpoints found in as_sir_method

Operator-precedence bug at line 1601:

  if (isTRUE(info) && nrow(df_unique) < 10 || nrow(breakpoints) == 0)

R evaluates && before ||, so this was equivalent to:

  (isTRUE(info) && nrow(df_unique) < 10) || (nrow(breakpoints) == 0)

When nrow(breakpoints) == 0 (e.g. cefoxitin / flucloxacillin / mupirocin
against E. coli in EUCAST) the intro message was always printed regardless
of info. Fix: add parentheses so info gates both conditions:

  isTRUE(info) && (nrow(df_unique) < 10 || nrow(breakpoints) == 0)

Also pass print = isTRUE(info) to progress_ticker so the progress bar
(which prints intro_txt as its title) is suppressed when info = FALSE.

https://claude.ai/code/session_012DXCXbZUC54Zij1z9bFiHR

* Fix cli formatting in as.sir() messages

- stop_if for empty ab_cols: wrap as.mic() and as.disk() in
  {.help [{.fun ...}](...)} for clickable links in cli output
- Parallel mode message: use {.field col} formatting for column names
  and quotes = FALSE in vector_and(), consistent with the rest of the
  codebase (avoids double-quoting from both font_bold and quotes="'")

https://claude.ai/code/session_012DXCXbZUC54Zij1z9bFiHR

* Use font_bold() inside {.field} for column names in parallel message

Convention: paste0("{.field ", font_bold(col), "}") gives bold green
column names without quotation marks, consistent with the rest of the
codebase (e.g. the 'Cleaning values' message in run_as_sir_column).

https://claude.ai/code/session_012DXCXbZUC54Zij1z9bFiHR

* Add collapse = NULL to font_bold() for column name vectors

font_bold() without collapse = NULL joins a vector with "" into a single
string, breaking paste0() element-wise formatting for length > 1 vectors.

https://claude.ai/code/session_012DXCXbZUC54Zij1z9bFiHR

* Add tools/ to .Rbuildignore

Keeps the benchmark script out of the built package tarball.

https://claude.ai/code/session_012DXCXbZUC54Zij1z9bFiHR

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-25 00:34:38 +02:00

26 KiB

AMR 3.0.1.9050

New

  • Support for clinical breakpoints of 2026 of both CLSI and EUCAST, by adding all of their over 5,700 new clinical breakpoints to the clinical_breakpoints data set for usage in as.sir(). EUCAST 2026 is now the new default guideline for all MIC and disk diffusion interpretations.
  • Integration with the tidymodels framework to allow seamless use of SIR, MIC and disk data in modelling pipelines via recipes
    • step_mic_log2() to transform <mic> columns with log2, and step_sir_numeric() to convert <sir> columns to numeric
    • New tidyselect helpers:
      • all_sir(), all_sir_predictors()
      • all_mic(), all_mic_predictors()
      • all_disk(), all_disk_predictors()
  • Data set esbl_isolates to practise with AMR modelling
  • AMR selectors ionophores(), peptides(), phosphonics() and spiropyrimidinetriones()
  • Support for Wildtype (WT) / Non-wildtype (NWT) in as.sir(), all plotting functions, and all susceptibility/resistance functions.
    • as.sir() gained an argument as_wt_nwt, which defaults to TRUE only when breakpoint_type = "ECOFF" (#254)
    • This transforms the output from S/R to WT/NWT
    • Functions such as susceptibility() count WT as S and NWT as R
  • Function interpretive_rules(), which allows future implementation of CLSI interpretive rules (#235)
    • eucast_rules() has become a wrapper around that function
    • Gained argument add_if_missing (default: TRUE). When set to FALSE, rules are only applied to cells that already contain an SIR value; NA cells are left untouched. This is useful with overwrite = TRUE to update reported results without imputing values for drugs that were not tested (#259)
  • Function amr_course(), which allows for automated download and unpacking of a GitHub repository for e.g. webinar use
  • Two new NA objects, NA_ab_ and NA_mo_, analogous to base R's NA_character_ and NA_integer_, for use in pipelines that require typed missing values

Fixes

  • Fixed multiple bugs in the parallel = TRUE mode of as.sir() for data frames: (1) PSOCK workers (Windows / R < 4.0) now correctly load the AMR package before processing, with a graceful fallback to sequential mode when the package cannot be loaded; (2) resolved stale-environment issue where the PSOCK path read a frozen copy of AMR_env instead of the live one, causing the wrong log entries to be captured; (3) fixed log-entry duplication in the fork-based path (mclapply) where pre-existing sir_interpretation_history rows were included in every worker's captured log; (4) removed use of non-exported internal functions (%pm>%, pm_pull, as.sir.default) from the worker closure, which made PSOCK workers fail; (5) suppressed per-column progress messages inside workers to prevent interleaved console output; (6) fixed a malformed Unicode escape \u00a (3 digits) in the "DONE" status message
  • Fixed a bug in as.sir() where values that were purely numeric (e.g., "1") and matched the broad SIR-matching regex would be incorrectly stripped of all content by the Unicode letter filter
  • Fixed a bug in as.mic() where MIC values in scientific notation (e.g., "1e-3") were incorrectly handled because the letter e was removed along with other Unicode letters; scientific notation e is now preserved
  • Fixed a bug in as.ab() where certain AB codes containing "PH" or "TH" (such as ETH, MTH, PHE, PHN, STH, THA, THI1) would incorrectly return NA when combined in a vector with any untranslatable value (#245)
  • Fixed a bug in antibiogram() for when no antimicrobials are set
  • Fixed a bug in as.sir() where for numeric input the arguments S, I, and R would not be considered (#244)
  • Fixed a bug in plotting MIC values when keep_operators = "all"
  • Fixed some foreign translations of antimicrobial drugs
  • Fixed a bug for printing column names to the console when using mutate_at(vars(...), as.mic) (#249)
  • Fixed a bug to disregard NI for susceptibility proportion functions
  • Fixed Italian translation of CoNS to Stafilococco coagulasi-negativo and CoPS to Stafilococco coagulasi-positivo (#256)
  • Fixed SIR and MIC coercion of combined values, e.g. as.sir("<= 0.002; S") or as.mic("S; 0.002") (#252)
  • Fixed translation of foreign languages in sir_df() (#272)
  • Fixed BRMO classification by including bacterial complexes (#275)
  • Fixed as.sir() for data frames silently deleting columns whose AB class was already <sir> when called a second time (re-running on already-converted data) (#278)
  • Fixed as.sir() for data frames incorrectly treating metadata columns (e.g. patient, ward) as antibiotic columns when their names coincidentally matched an antibiotic code; column content is now validated against AMR data patterns before inclusion
  • Improved parallel computing in as.sir(): when the number of AB columns is smaller than the number of available cores, rows are now split into batches so all cores stay active (row-batch mode). Previously, a 6-column dataset on a 16-core machine would only use 6 cores; now all 16 are used, with each worker processing a smaller row slice (lower per-worker memory pressure)
  • Fixed as.sir() ignoring info = FALSE for columns with no breakpoints (e.g. cefoxitin against E. coli): an operator-precedence bug (&&/||) caused the "Interpreting MIC values" intro message to fire unconditionally when nrow(breakpoints) == 0, regardless of info; the progress bar title was also not gated by info

Updates

  • Extensive cli integration for better message handling and clickable links in messages and warnings (#191, #265)
  • mdro() now infers resistance for a missing base drug column from an available corresponding drug+inhibitor combination showing resistance (e.g., piperacillin is absent but required, while piperacillin/tazobactam available and resistant). Can be set with the new argument infer_from_combinations, which defaults to TRUE (#209). Note that this can yield a higher MDRO detection (which is a good thing as it has become more reliable).
  • susceptibility() and resistance() gained the argument guideline, which defaults to EUCAST, for interpreting the 'I' category correctly.
  • Added to the antimicrobials data set: cefepime/taniborbactam (FTA), ceftibuten/avibactam (CTA), clorobiocin (CLB), kasugamycin (KAS), ostreogrycin (OST), taniborbactam (TAN), thiostrepton (THS), xeruborbactam (XER), and zorbamycin (ZOR)
  • as.mic() and rescale_mic() gained the argument round_to_next_log2, which can be set to TRUE to round all values up to the nearest next log2 level (#255)
  • antimicrobials$group is now a list instead of a character, to contain any group the drug is in (#246)
  • ab_group() gained an argument all_groups to return all groups the antimicrobial drug is in (#246)
  • Added explaining message to as.sir() when interpreting numeric values (e.g., 1 for S, 2 for I, 3 for R) (#244)
  • Updated handling of capped MIC values (<, <=, >, >=) in as.sir() in the argument capped_mic_handling: (#243)
    • Introduced four clearly defined options: "none", "conservative" (default), "standard", and "lenient"
    • Interpretation of capped MIC values now consistently returns "NI" (non-interpretable) when the true MIC could be at either side of a breakpoint, depending on the selected handling mode
    • This results in more reliable behaviour compared to previous versions for capped MIC values
    • Removed the "inverse" option, which has now become redundant
  • ab_group() now returns values consist with the AMR selectors (#246)
  • Added two new NA objects, NA_ab_ and NA_mo_, analogous to base R's NA_character_ and NA_integer_, for use in pipelines that require typed missing values

AMR 3.0.1

This is a bugfix release following the release of v3.0.0 in June 2025.

Changed

  • Fixed bugs introduced by ggplot2 v4.0.0 (#236)
    • MIC scale functions (such as scale_y_mic()) will now be applied automatically when plotting values of class mic
    • SIR scale functions (such as scale_x_sir()) will now be applied automatically when plotting values of class sir
  • Fixed a bug in antibiogram() for when no antimicrobials are set
  • Fixed a bug in antibiogram() to allow column names containing the + character (#222)
  • Fixed a bug in as.ab() for antimicrobial codes with a number in it if they are preceded by a space
  • Fixed a bug in eucast_rules() for using specific custom rules
  • Fixed a bug in as.sir() to allow any tidyselect language (#220)
  • Fixed a bug in as.sir() to pick right breakpoint when uti = FALSE (#216)
  • Fixed a bug in ggplot_sir() when using combine_SI = FALSE (#213)
  • Fixed a bug in mdro() to make sure all genes specified in arguments are acknowledged
  • Fixed a bug the antimicrobials data set to remove statins (#229)
  • Fixed a bug the microorganisms data set for MycoBank IDs and synonyms (#233)
  • Fixed ATC J01CR05 to map to piperacillin/tazobactam rather than piperacillin/sulbactam (#230)
  • Fixed skimmers (skimr package) of class ab, sir, and disk (#234)
  • Fixed all plotting to contain a separate colour for SDD (susceptible dose-dependent) (#223)
  • Fixed some specific Dutch translations for antimicrobials
  • Added a warning to as.ab() if input resembles antiviral codes or names (#232)
  • Added all reasons in verbose output of mdro() (#227)
  • Added names to age_groups() so that custom names can be given (#215)
  • Added note to as.sir() to make it explicit when higher-level taxonomic breakpoints are used (#218)
  • Added antibiotic codes from the Comprehensive Antibiotic Resistance Database (CARD) to the antimicrobials data set (#225)
  • Updated Fosfomycin to be of antibiotic class Phosphonics (#225)
  • Updated random_mic() and random_disk() to set skewedness of the distribution and allow multiple microorganisms

AMR 3.0.0

This package now supports not only tools for AMR data analysis in clinical settings, but also for veterinary and environmental microbiology. This was made possible through a collaboration with the University of Prince Edward Island's Atlantic Veterinary College, Canada. To celebrate this great improvement of the package, we also updated the package logo to reflect this change.

Breaking

  • Data set antibiotics has been renamed to antimicrobials as the data set contains more than just antibiotics. Using antibiotics will still work, but now returns a warning.
  • Removed all functions and references that used the deprecated rsi class, which were all replaced with their sir equivalents over two years ago.
  • Functions resistance_predict() and sir_predict() are now deprecated and will be removed in a future version. Use the tidymodels framework instead, for which we wrote a basic introduction.

New

  • One Health implementation
    • Function as.sir() now has extensive support for veterinary breakpoints from CLSI. Use breakpoint_type = "animal" and set the host argument to a variable that contains animal species names.
    • The clinical_breakpoints data set contains all these breakpoints, and can be downloaded on our download page.
    • The (new) antimicrobials data set contains all veterinary antimicrobials, such as pradofloxacin and enrofloxacin. All WHOCC codes for veterinary use have been added as well.
    • ab_atc() now supports ATC codes of veterinary antimicrobials (that all start with "Q")
    • ab_url() now supports retrieving the WHOCC url of their ATCvet pages
  • Support for WISCA antibiograms
    • The antibiogram() function now supports creating true Weighted-Incidence Syndromic Combination Antibiograms (WISCA), a powerful Bayesian method for estimating regimen coverage probabilities using pathogen incidence and antimicrobial susceptibility data. WISCA offers improved precision for syndrome-specific treatment, even in data sets with sparse data. A dedicated wisca() function is also available for easy usage.
  • More global coverage of languages
    • Added full support for 8 new languages: Arabic, Bengali, Hindi, Indonesian, Korean, Swahili, Urdu, and Vietnamese. The AMR package is now available in 28 languages.
  • Major update to fungal taxonomy and tools for mycologists
    • MycoBank has now been integrated as the primary taxonomic source for fungi. The microorganisms data set has been enriched with new columns (mycobank, mycobank_parent, and mycobank_renamed_to) that provide detailed information for fungal species.
    • A remarkable addition of over 20,000 new fungal records
    • New function mo_mycobank() to retrieve the MycoBank record number, analogous to existing functions such as mo_lpsn() and mo_gbif().
    • The as.mo() function and all mo_*() functions now include an only_fungi argument, allowing users to restrict results solely to fungal species. This ensures fungi are prioritised over bacteria during microorganism identification. This can also be set globally with the new AMR_only_fungi option.
    • Also updated other kingdoms, welcoming a total of 2,149 new records from 2023 and 927 from 2024.
  • Updated clinical breakpoints
    • Breakpoint of 2024 and 2025 of both CLSI and EUCAST are now supported, by adding all of their over 10,000 new clinical breakpoints to the clinical_breakpoints data set for usage in as.sir(). EUCAST 2025 is now the new default guideline for all MIC and disk diffusion interpretations.
    • Added all Expected Resistant Phenotypes from EUCAST (v1.2). The default rules for eucast_rules() are now: c("breakpoints", "expected_phenotypes").
    • Updated the intrinsic_resistant data set, which is now based on EUCAST Expected Resistant Phenotypes v1.2
    • as.sir() now brings additional factor levels: "NI" for non-interpretable and "SDD" for susceptible dose-dependent. Currently, the clinical_breakpoints data set contains 24 breakpoints that can return the value "SDD" instead of "I".
    • EUCAST interpretive rules (using eucast_rules()) are now available for EUCAST 12 (2022), 13 (2023), 14 (2024), and 15 (2025).
    • EUCAST dosage tables (dosage data set) are now available for EUCAST 13 (2023), 14 (2024), and 15 (2025).
  • New advanced ggplot2 extensions for MIC and SIR plotting and transforming
    • New function group scale_*_mic(), namely: scale_x_mic(), scale_y_mic(), scale_colour_mic() and scale_fill_mic(). They allow easy plotting of MIC values. They allow for manual range definition and plotting missing intermediate log2 levels.
    • New function group scale_*_sir(), namely: scale_x_sir(), scale_colour_sir() and scale_fill_sir(). They allow to plot the sir class, and translates into the system language at default. They also set colourblind-safe colours to the plots.
    • New function rescale_mic(), which allows users to rescale MIC values to a manually set range. This is the powerhouse behind the scale_*_mic() functions, but it can be used independently to, for instance, compare equality in MIC distributions by rescaling them to the same range first.
  • Support for Python
    • While using R for the heavy lifting, our 'AMR' Python Package was developed to run the AMR R package natively in Python. The Python package will always have the same version number as the R package, as it is built automatically with every code change.
  • Support for tidymodels
    • All antimicrobial selectors (such as aminoglycosides() and betalactams()) are now supported in tidymodels packages such as recipe and parsnip. See for more info our tutorial on using these AMR functions for predictive modelling.
  • Other
    • New function top_n_microorganisms() to filter a data set to the top n of any taxonomic property, e.g., filter to the top 3 species, filter to any species in the top 5 genera, or filter to the top 3 species in each of the top 5 genera
    • New function mo_group_members() to retrieve the member microorganisms of a microorganism group. For example, mo_group_members("Strep group C") returns a vector of all microorganisms that belong to that group.
    • New functions mic_p50() and mic_p90() to retrieve the 50th and 90th percentile of MIC values.

Changed

  • SIR interpretation
    • Support for parallel computing to greatly improve speed using the parallel package (part of base R). Use as.sir(your_data, parallel = TRUE) to run SIR interpretation using multiple cores.
    • It is now possible to use column names for arguments guideline, ab, mo, and uti: as.sir(..., ab = "column1", mo = "column2", uti = "column3"). This greatly improves the flexibility for users.
    • Users can now set their own criteria (using regular expressions) as to what should be considered S, I, R, SDD, and NI.
    • To get quantitative values, as.double() on a sir object will return 1 for S, 2 for SDD/I, and 3 for R (NI will become NA). Other functions using sir classes (e.g., summary()) are updated to reflect the change to contain NI and SDD.
    • Following CLSI interpretation rules, values outside the log2-dilution range will be rounded upwards to the nearest log2-level before interpretation. Only if using a CLSI guideline.
    • Combined MIC values (e.g., from CLSI) are now supported
    • The argument conserve_capped_values in as.sir() has been replaced with capped_mic_handling, which allows greater flexibility in handling capped MIC values (<, <=, >, >=). The four available options ("standard", "strict", "relaxed", "inverse") provide full control over whether these values should be interpreted conservatively or ignored. Using conserve_capped_values is now deprecated and returns a warning.
    • Added argument info to silence all console messages
  • antibiogram() function
    • Argument antibiotics has been renamed to antimicrobials. Using antibiotics will still work, but now returns a warning.
    • Added argument formatting_type to set any of the 22 options for the formatting of all 'cells'. This defaults to 18 for non-WISCA and 14 for WISCA, changing the output of antibiograms to cells with more info.
    • For this reason, add_total_n is now deprecated and FALSE at default since the denominators are added to the cells dependent on the formatting_type setting
    • The ab_transform argument now defaults to "name", displaying antibiotic column names instead of codes
  • Antimicrobial selectors (previously: antibiotic selectors)
    • 'Antibiotic selectors' are now called 'antimicrobial selectors' since their scope is broader than just antibiotics. All documentation have been updated, and ab_class() and ab_selector() have been replaced with amr_class() and amr_selector(). The old functions are now deprecated and will be removed in a future version.
    • Added selectors isoxazolylpenicillins(), monobactams(), nitrofurans(), phenicols(), rifamycins(), and sulfonamides()
    • When using antimicrobial selectors that exclude non-treatable drugs (such as gentamicin-high when using aminoglycosides()), the function now always returns a warning that these can be included using only_treatable = FALSE
    • Added a new argument return_all to all selectors, which defaults to TRUE to include any match. With FALSE, the old behaviour, only the first hit for each unique antimicrobial is returned.
    • All selectors can now be run as a separate command to retrieve a vector of all possible antimicrobials that the selector can select
    • The selectors lincosamides() and macrolides() do not overlap anymore - each antibiotic is now classified as either of these and not both
    • Fixed selector fluoroquinolones(), which now really only selects second-generation quinolones and up (first-generation quinolones do not contain a fluorine group)
  • antimicrobials data set
    • Added agents used for screening, with an ID all ending with -S: benzylpenicillin screening test (PEN-S), beta-lactamase screening test (BLA-S), cefotaxime screening test (CTX-S), clindamycin inducible screening test (CLI-S), nalidixic acid screening test (NAL-S), norfloxacin screening test (NOR-S), oxacillin screening test (OXA-S), pefloxacin screening test (PEF-S), and tetracycline screening test (TCY-S). The ID of cefoxitin screening was renamed from FOX1 to FOX-S, while the old code remains to work.
    • For this reason, the antimicrobial selectors cephalosporins(), cephalosporins_3rd(), lincosamides(), isoxazolylpenicillins(), quinolones(), fluoroquinolones(), and tetracyclines() now contain the argument only_treatable = TRUE (similar to other antimicrobial selectors that contain non-treatable drugs)
    • Added amorolfine (AMO, D01AE16), an antimycotic, which is now also part of the antifungals() selector
    • Added cefepime/enmetazobactam (FPE), a 4th gen cephalosporin
    • Added tigemonam (TNM), a monobactam
    • Added bleomycin (BLM), a glycopeptide
    • Added efflux (EFF), to allow mapping to AMRFinderPlus
    • Updated all ATC codes, trade names, and DDDs
  • MICs
    • Added as valid levels: 4096, 6 powers of 0.0625, and 5 powers of 192 (192, 384, 576, 768, 960)
    • Fixed a bug in as.mic() that failed translation of scientifically formatted numbers
    • Added new argument keep_operators to as.mic(). This can be "all" (default), "none", or "edges". This argument is also available in the new rescale_mic() and scale_*_mic() functions.
    • Comparisons of MIC values are now more strict. For example, >32 is higher than (and never equal to) 32. Thus, as.mic(">32") == as.mic(32) now returns FALSE, and as.mic(">32") > as.mic(32) now returns TRUE.
    • Sorting of MIC values (using sort()) was fixed in the same manner; <0.001 now gets sorted before 0.001, and >0.001 gets sorted after 0.001.
    • Intermediate log2 levels used for MIC plotting are now more common values instead of following a strict dilution range
    • is.mic() now returns a vector of TRUE/FALSE if the input is a data.frame, just like as.sir()
  • eucast_rules() now has an argument overwrite (default: FALSE) to indicate whether non-NA values should be overwritten
  • Disks of 0 to 5 mm are now allowed, the newly allowed range for disk diffusion (as.disk()) is now between 0 and 50 mm
  • Updated italicise_taxonomy() to support HTML output
  • custom_eucast_rules() now supports multiple antimicrobials and antimicrobial groups to be affected by a single rule
  • mo_info() now contains an extra element rank and group_members (with the contents of the new mo_group_members() function)
  • Updated all ATC codes from WHOCC
  • Updated all antimicrobial DDDs from WHOCC
  • Fix for using a manual value for mo_transform in antibiogram()
  • Fixed a bug for when antibiogram() returns an empty data set
  • Argument only_sir_columns now defaults to TRUE if any column of a data set contains a class 'sir' (functions eucast_rules(), key_antimicrobials(), mdro(), etc.)
  • Added Sensititre codes for animals, antimicrobials and microorganisms
  • Fix for mapping 'high level' antimicrobials in as.ab() (amphotericin B-high, gentamicin-high, kanamycin-high, streptomycin-high, tobramycin-high)
  • Improved overall algorithm of as.ab() for better performance and accuracy, including the new function as_reset_session() to remove earlier coercions.
  • Improved overall algorithm of as.mo() for better performance and accuracy, specifically:
    • More weight is given to genus and species combinations in cases where the subspecies is miswritten, so that the result will be the correct genus and species
    • Genera from the World Health Organization's (WHO) Priority Pathogen List now have the highest prevalence
  • Fixed a bug for sir_confidence_interval() when there are no isolates available
  • Updated the prevalence calculation to include genera from the World Health Organization's (WHO) Priority Pathogen List
  • Improved algorithm of first_isolate() when using the phenotype-based method, to prioritise records with the highest availability of SIR values
  • scale_y_percent() can now cope with ranges outside the 0-100% range
  • MDRO determination (using mdro())
    • The Verbose Mode (verbose = TRUE) now includes the guideline name
    • Implemented the new Dutch national MDRO guideline (SRI-richtlijn BRMO, Nov 2024)
    • Added arguments esbl, carbapenemase, mecA, mecC, vanA, vanB to denote column names or logical values indicating presence of these genes (or production of their proteins)
    • Added upport for antimicrobial selectors to use as as a custom rule (custom_mdro_guideline())
  • Added console colours support of sir class for Positron

Other

  • New website domain: https://amr-for-r.org! The old domain will remain to work.
  • Added Dr. Larisse Bolton and Aislinn Cook as contributors for their fantastic implementation of WISCA in a mathematically solid way
  • Added Matthew Saab, Dr. Jordan Stull, and Prof. Javier Sanchez as contributors for their tremendous input on veterinary breakpoints and interpretations
  • Added Prof. Kathryn Holt, Dr. Jane Hawkey, and Dr. Natacha Couto as contributors for their many suggestions, ideas and bugfixes
  • Greatly improved vctrs integration, a Tidyverse package working in the background for many Tidyverse functions. For users, this means that functions such as dplyr's bind_rows(), rowwise() and c_across() are now supported for e.g. columns of class mic. Despite this, this AMR package is still zero-dependent on any other package, including dplyr and vctrs.
  • Greatly updated and expanded documentation
  • Stopped support for SAS (.xpt) files, since their file structure and extremely inefficient and requires more disk space than GitHub allows in a single commit.

Older Versions

This changelog only contains changes from AMR v3.0 (June 2025) and later.