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

Extrapolating breakpoints for animals in line with CLSI VET09 document #165

Open
samueljpearce opened this issue Sep 6, 2024 · 5 comments
Labels
enhancement New feature or request

Comments

@samueljpearce
Copy link

Sorry, I know there are still bugs to iron out with breakpoints substitutions but I had an idea of how this could work in the future and wanted to write it down before I forgot. Basically, the CLSI are very specific about what breakpoints can be extrapolated for a given bug-drug combination in an animal species that does not have it's own breakpoints. This is outlined in the VET09 document. About 90% of the time, these are extrapolated from humans and not other animal species like this package is currently doing (with the exception of some canine breakpoints extrapolated for cats, but not all). On top of this, the M39 document states that antibiograms should specify when breakpoints have been extrapolated from other species and so separate antibiograms should be created for those interpreted with the patient species breakpoints and another for the extrapolated breakpoints.

In the long run, it would be amazing to work the VET09 extrapolation logic into the package as it is quite specific, but that is likely to be an onerous task and will require updating as and when new guidelines are released. In the meantime, I thought that the following may be an easier compromise, rather than the current substitutions based on a list of species in a particular order:

  • Allow users to specify what species (or a list of species in priority order) breakpoints will be extrapolated from.
  • Append a column to the dataset specifying which animal species these breakpoints have come from. This will allow easy filtering to create separate antibiograms based on where the breakpoints came from.
@samueljpearce
Copy link
Author

On second thought, appending a column wouldn't work as there may be breakpoints from different species used for a single isolate. Perhaps, returning a list with a separate data frame for data interpreted with breakpoints from different animal species would work? (E.g. first data frame with dog interpretations, second for where human breakpoints have been used because dog breakpoints didn't exist, etc.)

@msberends
Copy link
Owner

Thanks for bringing this up! I've been working with your colleagues from the University of Prince Edward Island's Atlantic Veterinary College, Canada, to implement this exact guideline. We actually discussed it yesterday and I updated the beta version today. Specifically, this part is directly from VET09:

AMR/R/sir.R

Lines 1261 to 1316 in 28bf91c

## fall-back methods for veterinary guidelines ----
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:
all_gram_pos_genera <- c("B_STPHY", "B_STRPT", "B_ENTRC", "B_PPTST", "B_AERCC", "B_MCRCCC", "B_TRPRL")
# HUMAN SUBSTITUTES
if (ab_current == "AZM" && mo_current_genus %in% all_gram_pos_genera && host_current %in% c("dogs", "cats", "horse")) {
# azithro can take human breakpoints for these agents
breakpoints_current <- breakpoints_current %pm>% subset(host == "human")
notes_current <- c(notes_current, paste0("Using ", font_bold("human"), " breakpoints for ", ab_formatted, " in Gram-positive cocci based on CLSI VET09."))
} else if (ab_current == "CTX" && mo_current_order == "B_[ORD]_ENTRBCTR" && host_current %in% c("dogs", "cats", "horse")) {
# cefotax can take human breakpoints for these agents
breakpoints_current <- breakpoints_current %pm>% subset(host == "human")
notes_current <- c(notes_current, paste0("Using ", font_bold("human"), " breakpoints for ", ab_formatted, " in Enterobacterales based on CLSI VET09."))
} else if (ab_current == "CAZ" && (mo_current_order == "B_[ORD]_ENTRBCTR" | mo_current == "B_PSDMN_AERG") && host_current %in% c("dogs", "cats", "horse")) {
# cefta can take human breakpoints for these agents
breakpoints_current <- breakpoints_current %pm>% subset(host == "human")
notes_current <- c(notes_current, paste0("Using ", font_bold("human"), " breakpoints for ", ab_formatted, " in Enterobacterales and ", font_italic("P. aeruginosa"), " based on CLSI VET09."))
} else if (ab_current == "ERY" && mo_current_genus %in% all_gram_pos_genera && host_current %in% c("dogs", "cats", "horse")) {
# erythro can take human breakpoints for these agents
breakpoints_current <- breakpoints_current %pm>% subset(host == "human")
notes_current <- c(notes_current, paste0("Using ", font_bold("human"), " breakpoints for ", ab_formatted, " in Gram-positive cocci based on CLSI VET09."))
} else if (ab_current == "IPM" && (mo_current_order == "B_[ORD]_ENTRBCTR" | mo_current == "B_PSDMN_AERG") && host_current %in% c("dogs", "cats", "horse")) {
# imipenem can take human breakpoints for these agents
breakpoints_current <- breakpoints_current %pm>% subset(host == "human")
notes_current <- c(notes_current, paste0("Using ", font_bold("human"), " breakpoints for ", ab_formatted, " in Enterobacterales and ", font_italic("P. aeruginosa"), " based on CLSI VET09."))
} else if (ab_current == "LNZ" && mo_current_genus %in% all_gram_pos_genera && host_current %in% c("dogs", "cats")) {
# linezolid can take human breakpoints for these agents
breakpoints_current <- breakpoints_current %pm>% subset(host == "human")
notes_current <- c(notes_current, paste0("Using ", font_bold("human"), " breakpoints for ", ab_formatted, " in staphylococci/enterococci based on CLSI VET09."))
} else if (ab_current == "NIT" && host_current %in% c("dogs", "cats")) {
# nitro can take human breakpoints for these agents
breakpoints_current <- breakpoints_current %pm>% subset(host == "human")
notes_current <- c(notes_current, paste0("Using ", font_bold("human"), " breakpoints for ", ab_formatted, " based on CLSI VET09."))
} else if (ab_current == "PEN" && mo_current_genus %in% all_gram_pos_genera && host_current %in% c("dogs", "cats")) {
# penicillin can take human breakpoints for these agents
breakpoints_current <- breakpoints_current %pm>% subset(host == "human")
notes_current <- c(notes_current, paste0("Using ", font_bold("human"), " breakpoints for ", ab_formatted, " in Gram-positive cocci based on CLSI VET09."))
} else if (ab_current == "RIF" && mo_current_genus %in% all_gram_pos_genera && host_current %in% c("dogs", "cats")) {
# rifampicin can take human breakpoints for staphylococci
breakpoints_current <- breakpoints_current %pm>% subset(host == "human")
notes_current <- c(notes_current, paste0("Using ", font_bold("human"), " breakpoints for ", ab_formatted, " in staphylococci based on CLSI VET09."))
} else if (ab_current == "SXT" && host_current %in% c("dogs", "cats", "horse")) {
# trimethoprim-sulfamethoxazole (TMS) can take human breakpoints for these agents
breakpoints_current <- breakpoints_current %pm>% subset(host == "human")
notes_current <- c(notes_current, paste0("Using ", font_bold("human"), " breakpoints for ", ab_formatted, " based on CLSI VET09."))
} else if (ab_current == "VAN" && host_current %in% c("dogs", "cats", "horse")) {
# vancomycin can take human breakpoints in these hosts
breakpoints_current <- breakpoints_current %pm>% subset(host == "human")
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")) {
# human breakpoints if no canine/feline
breakpoints_current <- breakpoints_current %pm>% subset(host == "human")
notes_current <- c(notes_current, paste0("Using ", font_bold("human"), " breakpoints for ", mo_formatted, " based on CLSI VET09."))

In the long run, it would be amazing to work the VET09 extrapolation logic into the package as it is quite specific, but that is likely to be an onerous task and will require updating as and when new guidelines are released. I

So that's a check for the first part, but maintaining hard-coded parts is indeed horrible. For a future version, we should aim to have this organised properly.

@msberends msberends added the enhancement New feature or request label Sep 19, 2024
@samueljpearce
Copy link
Author

That's amazing work! I had made a horrible work around involving a lot of subsetting data and interpreting it under different guidelines to eventually fill them all out correctly.

Two things to point out form the code you shared:

  • Gram positive breakpoints cannot be extrapolated to Enterococcus spp._ like other GPC
  • CLSI M39 states "The antibiogram should clearly delineate veterinary-approved vs other types of breakpoints used and results based on different breakpoints for a single agent should not be combined to generate a %S value". They go onto demonstrate this. So breakpoints extrapolated from humans should be presented separately and therefore this data needs to be identifiable from the rest of the SIR data. This is what I was referring to when suggesting returning a list of dataframes with the human interpretations separate to the others.

I completely agree it's not an easy problem and having hard-coded parts is a pain. Especially as this is likely to change with each release of the VET09 :(

@msberends
Copy link
Owner

msberends commented Sep 24, 2024

Gram positive breakpoints cannot be extrapolated to Enterococcus spp._ like other GPC

Oh really? That's what I understood from the Canadian colleagues, but maybe I got it wrong... I understood to 'all Gram+ cocci', means includes then of course Enterococcus. What about Micrococcus and Aerococcus and so forth?

So breakpoints extrapolated from humans should be presented separately and therefore this data needs to be identifiable from the rest of the SIR data.

I think they advise on reporting to clients who request diagnostics. In any case, we do provide sir_interpretation_history() where it is clear what was extrapolated based on VET09 and specifically from human breakpoints. Returning multiple lists is not feasible, as the data outcome structure should be consistent, irrespective of the guidelines used. There are notes in the console to inform users about this, and they can split the data based on the outcome of sir_interpretation_history(), which also contains row numbers of the input data. I think that should suffice.

@samueljpearce
Copy link
Author

samueljpearce commented Sep 24, 2024

Oh really? That's what the Canadian colleagues said... I understood to 'all Gram+ cocci', means includes then of course Enterococcus. What about Micrococcus and Aerococcus and so forth?

Unless I've interpreted it incorrectly, table 9 in VET09 says that GPC can be extrapolated to other GPC with the exception of Enterococcus spp. and other gram positive bacteria with known intrinsic resistance.

There are notes in the console to inform users about this, and they can split the data based on the outcome of sir_interpretation_history(), which also contains row numbers of the input data. I think that should suffice.

Ah sorry I didn't realise this, I will look into it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants