From 4e9fe05ee45bba407580d82052abb3d5c2f29a57 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 27 Jun 2026 11:54:02 +0000 Subject: [PATCH] Python wrapper update --- AMR.egg-info/PKG-INFO | 254 +++++++ AMR.egg-info/SOURCES.txt | 12 + AMR.egg-info/dependency_links.txt | 1 + AMR.egg-info/requires.txt | 3 + AMR.egg-info/top_level.txt | 1 + AMR/__init__.py | 249 +++++++ AMR/_engine.py | 93 +++ AMR/beta.py | 22 + AMR/datasets.py | 54 ++ AMR/functions.py | 984 +++++++++++++++++++++++++++ README.md | 226 ++++++ dist/amr-3.0.1.9078-py3-none-any.whl | Bin 0 -> 13407 bytes dist/amr-3.0.1.9078.tar.gz | Bin 0 -> 12640 bytes setup.py | 27 + 14 files changed, 1926 insertions(+) create mode 100644 AMR.egg-info/PKG-INFO create mode 100644 AMR.egg-info/SOURCES.txt create mode 100644 AMR.egg-info/dependency_links.txt create mode 100644 AMR.egg-info/requires.txt create mode 100644 AMR.egg-info/top_level.txt create mode 100644 AMR/__init__.py create mode 100644 AMR/_engine.py create mode 100644 AMR/beta.py create mode 100644 AMR/datasets.py create mode 100644 AMR/functions.py create mode 100755 README.md create mode 100644 dist/amr-3.0.1.9078-py3-none-any.whl create mode 100644 dist/amr-3.0.1.9078.tar.gz create mode 100644 setup.py diff --git a/AMR.egg-info/PKG-INFO b/AMR.egg-info/PKG-INFO new file mode 100644 index 000000000..ea58a33ce --- /dev/null +++ b/AMR.egg-info/PKG-INFO @@ -0,0 +1,254 @@ +Metadata-Version: 2.4 +Name: AMR +Version: 3.0.1.9078 +Summary: A Python wrapper for the AMR R package +Home-page: https://github.com/msberends/AMR +Author: Matthijs Berends +Author-email: m.s.berends@umcg.nl +License: GPL 2 +Project-URL: Bug Tracker, https://github.com/msberends/AMR/issues +Classifier: Programming Language :: Python :: 3 +Classifier: Operating System :: OS Independent +Requires-Python: >=3.6 +Description-Content-Type: text/markdown +Requires-Dist: rpy2 +Requires-Dist: numpy +Requires-Dist: pandas +Dynamic: author +Dynamic: author-email +Dynamic: classifier +Dynamic: description +Dynamic: description-content-type +Dynamic: home-page +Dynamic: license +Dynamic: project-url +Dynamic: requires-dist +Dynamic: requires-python +Dynamic: summary + + +The `AMR` package for R is a powerful tool for antimicrobial resistance (AMR) analysis. It provides extensive features for handling microbial and antimicrobial data. However, for those who work primarily in Python, we now have a more intuitive option available: the [`AMR` Python package](https://pypi.org/project/AMR/). + +This Python package is a wrapper around the `AMR` R package. It uses the `rpy2` package internally. Despite the need to have R installed, Python users can now easily work with AMR data directly through Python code. + +# Prerequisites + +This package was only tested with a [virtual environment (venv)](https://docs.python.org/3/library/venv.html). You can set up such an environment by running: + +```python +# linux and macOS: +python -m venv /path/to/new/virtual/environment + +# Windows: +python -m venv C:\path\to\new\virtual\environment +``` + +Then you can [activate the environment](https://docs.python.org/3/library/venv.html#how-venvs-work), after which the venv is ready to work with. + +# Install AMR + +1. Since the Python package is available on the official [Python Package Index](https://pypi.org/project/AMR/), you can just run: + + ```bash + pip install AMR + ``` + +2. Make sure you have R installed. There is **no need to install the `AMR` R package**, as it will be installed automatically. + + For Linux: + + ```bash + # Ubuntu / Debian + sudo apt install r-base + # Fedora: + sudo dnf install R + # CentOS/RHEL + sudo yum install R + ``` + + For macOS (using [Homebrew](https://brew.sh)): + + ```bash + brew install r + ``` + + For Windows, visit the [CRAN download page](https://cran.r-project.org) to download and install R. + +# Examples of Usage + +## Cleaning Taxonomy + +Here’s an example that demonstrates how to clean microorganism and drug names using the `AMR` Python package: + +```python +import pandas as pd +import AMR + +# Sample data +data = { + "MOs": ['E. coli', 'ESCCOL', 'esco', 'Esche coli'], + "Drug": ['Cipro', 'CIP', 'J01MA02', 'Ciproxin'] +} +df = pd.DataFrame(data) + +# Use AMR functions to clean microorganism and drug names +df['MO_clean'] = AMR.mo_name(df['MOs']) +df['Drug_clean'] = AMR.ab_name(df['Drug']) + +# Display the results +print(df) +``` + +| MOs | Drug | MO_clean | Drug_clean | +|-------------|-----------|--------------------|---------------| +| E. coli | Cipro | Escherichia coli | Ciprofloxacin | +| ESCCOL | CIP | Escherichia coli | Ciprofloxacin | +| esco | J01MA02 | Escherichia coli | Ciprofloxacin | +| Esche coli | Ciproxin | Escherichia coli | Ciprofloxacin | + +### Explanation + +* **mo_name:** This function standardises microorganism names. Here, different variations of *Escherichia coli* (such as "E. coli", "ESCCOL", "esco", and "Esche coli") are all converted into the correct, standardised form, "Escherichia coli". + +* **ab_name**: Similarly, this function standardises antimicrobial names. The different representations of ciprofloxacin (e.g., "Cipro", "CIP", "J01MA02", and "Ciproxin") are all converted to the standard name, "Ciprofloxacin". + +## Calculating AMR + +```python +import AMR +import pandas as pd + +df = AMR.example_isolates +result = AMR.resistance(df["AMX"]) +print(result) +``` + +``` +[0.59555556] +``` + +## Generating Antibiograms + +One of the core functions of the `AMR` package is generating an antibiogram, a table that summarises the antimicrobial susceptibility of bacterial isolates. Here’s how you can generate an antibiogram from Python: + +```python +result2a = AMR.antibiogram(df[["mo", "AMX", "CIP", "TZP"]]) +print(result2a) +``` + +| Pathogen | Amoxicillin | Ciprofloxacin | Piperacillin/tazobactam | +|-----------------|-----------------|-----------------|--------------------------| +| CoNS | 7% (10/142) | 73% (183/252) | 30% (10/33) | +| E. coli | 50% (196/392) | 88% (399/456) | 94% (393/416) | +| K. pneumoniae | 0% (0/58) | 96% (53/55) | 89% (47/53) | +| P. aeruginosa | 0% (0/30) | 100% (30/30) | None | +| P. mirabilis | None | 94% (34/36) | None | +| S. aureus | 6% (8/131) | 90% (171/191) | None | +| S. epidermidis | 1% (1/91) | 64% (87/136) | None | +| S. hominis | None | 80% (56/70) | None | +| S. pneumoniae | 100% (112/112) | None | 100% (112/112) | + + +```python +result2b = AMR.antibiogram(df[["mo", "AMX", "CIP", "TZP"]], mo_transform = "gramstain") +print(result2b) +``` + +| Pathogen | Amoxicillin | Ciprofloxacin | Piperacillin/tazobactam | +|----------------|-----------------|------------------|--------------------------| +| Gram-negative | 36% (226/631) | 91% (621/684) | 88% (565/641) | +| Gram-positive | 43% (305/703) | 77% (560/724) | 86% (296/345) | + + +In this example, we generate an antibiogram by selecting various antibiotics. + +## Taxonomic Data Sets Now in Python! + +As a Python user, you might like that the most important data sets of the `AMR` R package, `microorganisms`, `antimicrobials`, `clinical_breakpoints`, and `example_isolates`, are now available as regular Python data frames: + +```python +AMR.microorganisms +``` + +| mo | fullname | status | kingdom | gbif | gbif_parent | gbif_renamed_to | prevalence | +|--------------|------------------------------------|----------|----------|-----------|-------------|-----------------|------------| +| B_GRAMN | (unknown Gram-negatives) | unknown | Bacteria | None | None | None | 2.0 | +| B_GRAMP | (unknown Gram-positives) | unknown | Bacteria | None | None | None | 2.0 | +| B_ANAER-NEG | (unknown anaerobic Gram-negatives) | unknown | Bacteria | None | None | None | 2.0 | +| B_ANAER-POS | (unknown anaerobic Gram-positives) | unknown | Bacteria | None | None | None | 2.0 | +| B_ANAER | (unknown anaerobic bacteria) | unknown | Bacteria | None | None | None | 2.0 | +| ... | ... | ... | ... | ... | ... | ... | ... | +| B_ZYMMN_POMC | Zymomonas pomaceae | accepted | Bacteria | 10744418 | 3221412 | None | 2.0 | +| B_ZYMPH | Zymophilus | synonym | Bacteria | None | 9475166 | None | 2.0 | +| B_ZYMPH_PCVR | Zymophilus paucivorans | synonym | Bacteria | None | None | None | 2.0 | +| B_ZYMPH_RFFN | Zymophilus raffinosivorans | synonym | Bacteria | None | None | None | 2.0 | +| F_ZYZYG | Zyzygomyces | unknown | Fungi | None | 7581 | None | 2.0 | + +```python +AMR.antimicrobials +``` + +| ab | cid | name | group | oral_ddd | oral_units | iv_ddd | iv_units | +|-----|-------------|----------------------|----------------------------|----------|------------|--------|----------| +| AMA | 4649.0 | 4-aminosalicylic acid| Antimycobacterials | 12.00 | g | NaN | None | +| ACM | 6450012.0 | Acetylmidecamycin | Macrolides/lincosamides | NaN | None | NaN | None | +| ASP | 49787020.0 | Acetylspiramycin | Macrolides/lincosamides | NaN | None | NaN | None | +| ALS | 8954.0 | Aldesulfone sodium | Other antibacterials | 0.33 | g | NaN | None | +| AMK | 37768.0 | Amikacin | Aminoglycosides | NaN | None | 1.0 | g | +| ... | ... | ... | ... | ... | ... | ... | ... | +| VIR | 11979535.0 | Virginiamycine | Other antibacterials | NaN | None | NaN | None | +| VOR | 71616.0 | Voriconazole | Antifungals/antimycotics | 0.40 | g | 0.4 | g | +| XBR | 72144.0 | Xibornol | Other antibacterials | NaN | None | NaN | None | +| ZID | 77846445.0 | Zidebactam | Other antibacterials | NaN | None | NaN | None | +| ZFD | NaN | Zoliflodacin | None | NaN | None | NaN | None | + + +# Installation Channels + +## Stable Release (CRAN) + +The default `AMR` Python package uses the latest stable version of the `AMR` R package, published on CRAN. After running `pip install AMR`, import it as usual: + +```python +import AMR + +AMR.example_isolates +``` + +## Development Version (GitHub) + +To use the latest development version of the `AMR` R package (sourced directly from GitHub), import the `beta` sub-package and alias it as `AMR`: + +```python +import AMR.beta as AMR + +AMR.example_isolates +``` + +Aliasing with `as AMR` keeps all downstream code identical to the stable import. Switching between the stable release and the development version requires changing only the import line — nothing else in your script needs to change. + +# SIR Classification with `as_sir()` + +## Using `enforce_method` + +The `as_sir()` function in R uses S3 method dispatch to select the correct calculation method based on the input class: `` for MIC values and `` for disk diffusion values. Because Python objects do not carry R class attributes through the `rpy2` bridge, this automatic dispatch may not resolve correctly. + +To explicitly specify the input type, use the `enforce_method` argument: + +```python +# Treat the column as MIC values — maps to R's as.sir.mic() +AMR.as_sir(df["MIC_col"], mo="E. coli", ab="AMX", guideline="EUCAST", enforce_method="mic") + +# Treat the column as disk diffusion values — maps to R's as.sir.disk() +AMR.as_sir(df["disk_col"], mo="E. coli", ab="AMX", guideline="EUCAST", enforce_method="disk") +``` + +Without `enforce_method`, R falls back to class-based dispatch on the raw Python input, which may fail or return unexpected results. Always supply `enforce_method` when calling `as_sir()` from Python. + +# Conclusion + +With the `AMR` Python package, Python users can now effortlessly call R functions from the `AMR` R package. This eliminates the need for complex `rpy2` configurations and provides a clean, easy-to-use interface for antimicrobial resistance analysis. The examples provided above demonstrate how this can be applied to typical workflows, such as standardising microorganism and antimicrobial names or calculating resistance. + +By just running `import AMR`, users can seamlessly integrate the robust features of the R `AMR` package into Python workflows. + +Whether you're cleaning data or analysing resistance patterns, the `AMR` Python package makes it easy to work with AMR data in Python. diff --git a/AMR.egg-info/SOURCES.txt b/AMR.egg-info/SOURCES.txt new file mode 100644 index 000000000..617d18f78 --- /dev/null +++ b/AMR.egg-info/SOURCES.txt @@ -0,0 +1,12 @@ +README.md +setup.py +AMR/__init__.py +AMR/_engine.py +AMR/beta.py +AMR/datasets.py +AMR/functions.py +AMR.egg-info/PKG-INFO +AMR.egg-info/SOURCES.txt +AMR.egg-info/dependency_links.txt +AMR.egg-info/requires.txt +AMR.egg-info/top_level.txt \ No newline at end of file diff --git a/AMR.egg-info/dependency_links.txt b/AMR.egg-info/dependency_links.txt new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/AMR.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/AMR.egg-info/requires.txt b/AMR.egg-info/requires.txt new file mode 100644 index 000000000..fb2bcf682 --- /dev/null +++ b/AMR.egg-info/requires.txt @@ -0,0 +1,3 @@ +rpy2 +numpy +pandas diff --git a/AMR.egg-info/top_level.txt b/AMR.egg-info/top_level.txt new file mode 100644 index 000000000..18f3926f7 --- /dev/null +++ b/AMR.egg-info/top_level.txt @@ -0,0 +1 @@ +AMR diff --git a/AMR/__init__.py b/AMR/__init__.py new file mode 100644 index 000000000..741874607 --- /dev/null +++ b/AMR/__init__.py @@ -0,0 +1,249 @@ +import sys + +_DATASETS = frozenset({ + 'example_isolates', 'microorganisms', + 'antimicrobials', 'clinical_breakpoints' +}) + +class _AMRModule(type(sys.modules[__name__])): + """Lazy-loading module: nothing runs until an attribute is accessed.""" + + def __getattr__(self, name): + if name in _DATASETS: + from .datasets import get + return get(name, source="cran") + try: + from . import functions + return getattr(functions, name) + except AttributeError: + raise AttributeError( + f"module 'AMR' has no attribute '{name}'") + +sys.modules[__name__].__class__ = _AMRModule +from .functions import custom_eucast_rules +from .functions import ab_class +from .functions import ab_selector +from .functions import ab_from_text +from .functions import ab_name +from .functions import ab_cid +from .functions import ab_synonyms +from .functions import ab_tradenames +from .functions import ab_group +from .functions import ab_atc +from .functions import ab_atc_group1 +from .functions import ab_atc_group2 +from .functions import ab_loinc +from .functions import ab_ddd +from .functions import ab_ddd_units +from .functions import ab_info +from .functions import ab_url +from .functions import ab_property +from .functions import add_custom_antimicrobials +from .functions import clear_custom_antimicrobials +from .functions import add_custom_microorganisms +from .functions import clear_custom_microorganisms +from .functions import age +from .functions import age_groups +from .functions import all_sir +from .functions import all_sir_predictors +from .functions import all_mic +from .functions import all_mic_predictors +from .functions import all_disk +from .functions import all_disk_predictors +from .functions import step_mic_log2 +from .functions import step_sir_numeric +from .functions import amr_course +from .functions import wisca +from .functions import antibiogram +from .functions import retrieve_wisca_parameters +from .functions import wisca_plot +from .functions import aminoglycosides +from .functions import aminopenicillins +from .functions import antifungals +from .functions import antimycobacterials +from .functions import betalactams +from .functions import betalactams_with_inhibitor +from .functions import carbapenems +from .functions import cephalosporins +from .functions import cephalosporins_1st +from .functions import cephalosporins_2nd +from .functions import cephalosporins_3rd +from .functions import cephalosporins_4th +from .functions import cephalosporins_5th +from .functions import fluoroquinolones +from .functions import glycopeptides +from .functions import ionophores +from .functions import isoxazolylpenicillins +from .functions import lincosamides +from .functions import lipoglycopeptides +from .functions import macrolides +from .functions import monobactams +from .functions import nitrofurans +from .functions import oxazolidinones +from .functions import penicillins +from .functions import peptides +from .functions import phenicols +from .functions import phosphonics +from .functions import polymyxins +from .functions import quinolones +from .functions import rifamycins +from .functions import spiropyrimidinetriones +from .functions import streptogramins +from .functions import sulfonamides +from .functions import tetracyclines +from .functions import trimethoprims +from .functions import ureidopenicillins +from .functions import amr_class +from .functions import amr_selector +from .functions import administrable_per_os +from .functions import administrable_iv +from .functions import not_intrinsic_resistant +from .functions import as_ab +from .functions import is_ab +from .functions import ab_reset_session +from .functions import as_av +from .functions import is_av +from .functions import as_disk +from .functions import is_disk +from .functions import as_mic +from .functions import is_mic +from .functions import rescale_mic +from .functions import mic_p50 +from .functions import mic_p90 +from .functions import as_mo +from .functions import is_mo +from .functions import mo_uncertainties +from .functions import mo_renamed +from .functions import mo_failures +from .functions import mo_reset_session +from .functions import mo_cleaning_regex +from .functions import as_sir +from .functions import is_sir +from .functions import is_sir_eligible +from .functions import sir_interpretation_history +from .functions import atc_online_property +from .functions import atc_online_groups +from .functions import atc_online_ddd +from .functions import atc_online_ddd_units +from .functions import av_from_text +from .functions import av_name +from .functions import av_cid +from .functions import av_synonyms +from .functions import av_tradenames +from .functions import av_group +from .functions import av_atc +from .functions import av_loinc +from .functions import av_ddd +from .functions import av_ddd_units +from .functions import av_info +from .functions import av_url +from .functions import av_property +from .functions import availability +from .functions import bug_drug_combinations +from .functions import count_resistant +from .functions import count_susceptible +from .functions import count_S +from .functions import count_SI +from .functions import count_I +from .functions import count_IR +from .functions import count_R +from .functions import count_all +from .functions import n_sir +from .functions import count_df +from .functions import custom_interpretive_rules +from .functions import custom_mdro_guideline +from .functions import export_ncbi_biosample +from .functions import first_isolate +from .functions import filter_first_isolate +from .functions import g_test +from .functions import is_new_episode +from .functions import ggplot_pca +from .functions import ggplot_sir +from .functions import geom_sir +from .functions import guess_ab_col +from .functions import interpretive_rules +from .functions import eucast_rules +from .functions import clsi_rules +from .functions import eucast_dosage +from .functions import italicise_taxonomy +from .functions import italicize_taxonomy +from .functions import inner_join_microorganisms +from .functions import left_join_microorganisms +from .functions import right_join_microorganisms +from .functions import full_join_microorganisms +from .functions import semi_join_microorganisms +from .functions import anti_join_microorganisms +from .functions import key_antimicrobials +from .functions import all_antimicrobials +from .functions import kurtosis +from .functions import like +from .functions import mdro +from .functions import brmo +from .functions import mrgn +from .functions import mdr_tb +from .functions import mdr_cmi2012 +from .functions import eucast_exceptional_phenotypes +from .functions import mean_amr_distance +from .functions import amr_distance_from_row +from .functions import mo_matching_score +from .functions import mo_name +from .functions import mo_fullname +from .functions import mo_shortname +from .functions import mo_subspecies +from .functions import mo_species +from .functions import mo_genus +from .functions import mo_family +from .functions import mo_order +from .functions import mo_class +from .functions import mo_phylum +from .functions import mo_kingdom +from .functions import mo_domain +from .functions import mo_type +from .functions import mo_status +from .functions import mo_pathogenicity +from .functions import mo_gramstain +from .functions import mo_is_gram_negative +from .functions import mo_is_gram_positive +from .functions import mo_is_yeast +from .functions import mo_is_intrinsic_resistant +from .functions import mo_oxygen_tolerance +from .functions import mo_is_anaerobic +from .functions import mo_morphology +from .functions import mo_snomed +from .functions import mo_ref +from .functions import mo_authors +from .functions import mo_year +from .functions import mo_lpsn +from .functions import mo_mycobank +from .functions import mo_gbif +from .functions import mo_rank +from .functions import mo_taxonomy +from .functions import mo_synonyms +from .functions import mo_current +from .functions import mo_group_members +from .functions import mo_info +from .functions import mo_url +from .functions import mo_property +from .functions import pca +from .functions import theme_sir +from .functions import labels_sir_count +from .functions import resistance +from .functions import susceptibility +from .functions import sir_confidence_interval +from .functions import proportion_R +from .functions import proportion_IR +from .functions import proportion_I +from .functions import proportion_SI +from .functions import proportion_S +from .functions import proportion_df +from .functions import sir_df +from .functions import random_mic +from .functions import random_disk +from .functions import random_sir +from .functions import resistance_predict +from .functions import sir_predict +from .functions import ggplot_sir_predict +from .functions import skewness +from .functions import top_n_microorganisms +from .functions import reset_AMR_locale +from .functions import translate_AMR diff --git a/AMR/_engine.py b/AMR/_engine.py new file mode 100644 index 000000000..cc6c5d9ff --- /dev/null +++ b/AMR/_engine.py @@ -0,0 +1,93 @@ +import os +import sys +import importlib.metadata as metadata + +# Get the path to the virtual environment +venv_path = sys.prefix +r_lib_path = os.path.join(venv_path, "R_libs") +os.makedirs(r_lib_path, exist_ok=True) + +# Set environment variable before importing rpy2 +os.environ['R_LIBS_SITE'] = r_lib_path + +from rpy2 import robjects +from rpy2.robjects.vectors import StrVector +from rpy2.robjects.packages import importr, isinstalled + +# Import base and utils once +base = importr('base') +utils = importr('utils') + +# Silence R console output entirely +robjects.r('suppressMessages(suppressWarnings(sink(tempfile())))') +base._libPaths(r_lib_path) + +_installed_source = None + +def _r_version(): + """Return the currently installed AMR R package version, or None.""" + try: + return str(robjects.r( + f'as.character(packageVersion("AMR", lib.loc = "{r_lib_path}"))')[0]) + except Exception: + return None + +def _py_version(): + """Return the Python AMR package version from metadata, or empty string.""" + try: + return str(metadata.version('AMR')) + except metadata.PackageNotFoundError: + return '' + +def _install_cran(): + """Install AMR from CRAN into the isolated library.""" + print("AMR: Installing from CRAN...", flush=True) + utils.install_packages( + 'AMR', + repos='https://cloud.r-project.org', + lib=r_lib_path, + quiet=True + ) + +def _install_github(): + """Install AMR development version from GitHub into the isolated library.""" + print("AMR: Installing development version from GitHub...", flush=True) + utils.install_packages( + StrVector(['remotes', 'desc']), + repos='https://cloud.r-project.org', + lib=r_lib_path, + quiet=True + ) + remotes = importr('remotes', lib_loc=r_lib_path) + remotes.install_github('msberends/AMR', lib=r_lib_path, quiet=True) + +def ensure_amr(source="cran"): + """Ensure AMR is installed from the requested source. Idempotent per source.""" + global _installed_source + + if _installed_source == source: + return + + install_fn = _install_github if source == "github" else _install_cran + + if not isinstalled('AMR', lib_loc=r_lib_path): + install_fn() + else: + # Check for version mismatch and update if needed + r_ver = _r_version() + py_ver = _py_version() + if r_ver != py_ver: + try: + install_fn() + except Exception as e: + print(f"AMR: Could not update ({e})", flush=True) + + print(f"AMR: R package version {_r_version()} ready.", flush=True) + _installed_source = source + +def restore_sink(): + """Restore R console output after setup is complete.""" + try: + robjects.r('sink()') + except Exception: + pass diff --git a/AMR/beta.py b/AMR/beta.py new file mode 100644 index 000000000..df55d4f81 --- /dev/null +++ b/AMR/beta.py @@ -0,0 +1,22 @@ +import sys + +_DATASETS = frozenset({ + 'example_isolates', 'microorganisms', + 'antimicrobials', 'clinical_breakpoints' +}) + +class _BetaModule(type(sys.modules[__name__])): + """Lazy-loading module: installs AMR from GitHub on first access.""" + + def __getattr__(self, name): + if name in _DATASETS: + from .datasets import get + return get(name, source="github") + try: + from . import functions + return getattr(functions, name) + except AttributeError: + raise AttributeError( + f"module 'AMR.beta' has no attribute '{name}'") + +sys.modules[__name__].__class__ = _BetaModule diff --git a/AMR/datasets.py b/AMR/datasets.py new file mode 100644 index 000000000..1c84065e7 --- /dev/null +++ b/AMR/datasets.py @@ -0,0 +1,54 @@ +import pandas as pd +from rpy2 import robjects +from rpy2.robjects.conversion import localconverter +from rpy2.robjects import default_converter, numpy2ri, pandas2ri + +from ._engine import ensure_amr, restore_sink + +_cache = {} +_loaded_source = None + +def _load_datasets(source="cran"): + """Load all AMR datasets into the module cache.""" + global _loaded_source + + if _cache and _loaded_source == source: + return + + if _cache and _loaded_source != source: + _cache.clear() + + ensure_amr(source) + + with localconverter(default_converter + numpy2ri.converter + pandas2ri.converter): + _cache['example_isolates'] = _load_example_isolates() + _cache['microorganisms'] = robjects.r( + 'AMR::microorganisms[, !sapply(AMR::microorganisms, is.list)]') + _cache['antimicrobials'] = robjects.r( + 'AMR::antimicrobials[, !sapply(AMR::antimicrobials, is.list)]') + _cache['clinical_breakpoints'] = robjects.r( + 'AMR::clinical_breakpoints[, !sapply(AMR::clinical_breakpoints, is.list)]') + + restore_sink() + _loaded_source = source + +def _load_example_isolates(): + df = robjects.r(''' + df <- AMR::example_isolates + df[] <- lapply(df, function(x) { + if (inherits(x, c("Date", "POSIXt", "factor"))) { + as.character(x) + } else { + x + } + }) + df <- df[, !sapply(df, is.list)] + df + ''') + df['date'] = pd.to_datetime(df['date']) + return df + +def get(name, source="cran"): + """Retrieve a dataset by name, installing AMR if needed.""" + _load_datasets(source) + return _cache[name] diff --git a/AMR/functions.py b/AMR/functions.py new file mode 100644 index 000000000..d8eef8f9b --- /dev/null +++ b/AMR/functions.py @@ -0,0 +1,984 @@ +import functools +import rpy2.robjects as robjects +from rpy2.robjects.packages import importr +from rpy2.robjects.vectors import StrVector, FactorVector, IntVector, FloatVector, DataFrame +from rpy2.robjects.conversion import localconverter +from rpy2.robjects import default_converter, numpy2ri, pandas2ri +import pandas as pd +import numpy as np + +from ._engine import ensure_amr + +# Ensure AMR is available before importing it in R +ensure_amr("cran") +amr_r = importr('AMR') + +def convert_to_r(value): + """Convert Python lists/tuples to typed R vectors. + + rpy2's default_converter passes Python lists to R as R lists, not as + character/numeric vectors. This causes element-wise type-check functions + such as is.mic(), is.sir(), and is.disk() to return a logical vector + rather than a single logical, breaking R's scalar && operator. + + This helper converts Python lists and tuples to the appropriate R vector + type based on the element types, so R always receives a proper vector.""" + if isinstance(value, (list, tuple)): + if len(value) == 0: + return StrVector([]) + # bool must be checked before int because bool is a subclass of int + if all(isinstance(v, bool) for v in value): + return robjects.vectors.BoolVector(value) + if all(isinstance(v, int) for v in value): + return IntVector(value) + if all(isinstance(v, float) for v in value): + return FloatVector(value) + if all(isinstance(v, str) for v in value): + return StrVector(value) + # Mixed types: coerce all to string + return StrVector([str(v) for v in value]) + return value + +def convert_to_python(r_output): + # Check if it's a StrVector (R character vector) + if isinstance(r_output, StrVector): + return list(r_output) # Convert to a Python list of strings + + # Check if it's a FactorVector (R factor) + elif isinstance(r_output, FactorVector): + return list(r_output) # Convert to a list of integers (factor levels) + + # Check if it's an IntVector or FloatVector (numeric R vectors) + elif isinstance(r_output, (IntVector, FloatVector)): + return list(r_output) # Convert to a Python list of integers or floats + + # Check if it's a pandas-compatible R data frame + elif isinstance(r_output, (pd.DataFrame, DataFrame)): + return r_output # Return as pandas DataFrame (already converted by pandas2ri) + + # Check if the input is a NumPy array and has a string data type + if isinstance(r_output, np.ndarray) and np.issubdtype(r_output.dtype, np.str_): + return r_output.tolist() # Convert to a regular Python list + + # Fall-back + return r_output + +def r_to_python(r_func): + """Decorator that converts Python list/tuple inputs to typed R vectors, + runs the rpy2 function under a localconverter, and converts the output + to a Python type.""" + @functools.wraps(r_func) + def wrapper(*args, **kwargs): + args = tuple(convert_to_r(a) for a in args) + kwargs = {k: convert_to_r(v) for k, v in kwargs.items()} + with localconverter(default_converter + numpy2ri.converter + pandas2ri.converter): + return convert_to_python(r_func(*args, **kwargs)) + return wrapper +@r_to_python +def custom_eucast_rules(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.custom_eucast_rules(*args, **kwargs) +@r_to_python +def ab_class(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ab_class(*args, **kwargs) +@r_to_python +def ab_selector(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ab_selector(*args, **kwargs) +@r_to_python +def ab_from_text(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ab_from_text(*args, **kwargs) +@r_to_python +def ab_name(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ab_name(x, *args, **kwargs) +@r_to_python +def ab_cid(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ab_cid(x, *args, **kwargs) +@r_to_python +def ab_synonyms(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ab_synonyms(x, *args, **kwargs) +@r_to_python +def ab_tradenames(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ab_tradenames(x, *args, **kwargs) +@r_to_python +def ab_group(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ab_group(x, *args, **kwargs) +@r_to_python +def ab_atc(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ab_atc(x, *args, **kwargs) +@r_to_python +def ab_atc_group1(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ab_atc_group1(x, *args, **kwargs) +@r_to_python +def ab_atc_group2(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ab_atc_group2(x, *args, **kwargs) +@r_to_python +def ab_loinc(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ab_loinc(x, *args, **kwargs) +@r_to_python +def ab_ddd(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ab_ddd(x, *args, **kwargs) +@r_to_python +def ab_ddd_units(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ab_ddd_units(x, *args, **kwargs) +@r_to_python +def ab_info(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ab_info(x, *args, **kwargs) +@r_to_python +def ab_url(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ab_url(x, *args, **kwargs) +@r_to_python +def ab_property(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ab_property(x, *args, **kwargs) +@r_to_python +def add_custom_antimicrobials(x): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.add_custom_antimicrobials(x) +@r_to_python +def clear_custom_antimicrobials(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.clear_custom_antimicrobials(*args, **kwargs) +@r_to_python +def add_custom_microorganisms(x): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.add_custom_microorganisms(x) +@r_to_python +def clear_custom_microorganisms(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.clear_custom_microorganisms(*args, **kwargs) +@r_to_python +def age(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.age(x, *args, **kwargs) +@r_to_python +def age_groups(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.age_groups(x, *args, **kwargs) +@r_to_python +def all_sir(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.all_sir(*args, **kwargs) +@r_to_python +def all_sir_predictors(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.all_sir_predictors(*args, **kwargs) +@r_to_python +def all_mic(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.all_mic(*args, **kwargs) +@r_to_python +def all_mic_predictors(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.all_mic_predictors(*args, **kwargs) +@r_to_python +def all_disk(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.all_disk(*args, **kwargs) +@r_to_python +def all_disk_predictors(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.all_disk_predictors(*args, **kwargs) +@r_to_python +def step_mic_log2(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.step_mic_log2(*args, **kwargs) +@r_to_python +def step_sir_numeric(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.step_sir_numeric(*args, **kwargs) +@r_to_python +def amr_course(github_repo, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.amr_course(github_repo, *args, **kwargs) +@r_to_python +def wisca(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.wisca(*args, **kwargs) +@r_to_python +def antibiogram(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.antibiogram(*args, **kwargs) +@r_to_python +def retrieve_wisca_parameters(wisca_model, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.retrieve_wisca_parameters(wisca_model, *args, **kwargs) +@r_to_python +def wisca_plot(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.wisca_plot(*args, **kwargs) +@r_to_python +def aminoglycosides(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.aminoglycosides(*args, **kwargs) +@r_to_python +def aminopenicillins(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.aminopenicillins(only_sir_columns = False, *args, **kwargs) +@r_to_python +def antifungals(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.antifungals(only_sir_columns = False, *args, **kwargs) +@r_to_python +def antimycobacterials(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.antimycobacterials(only_sir_columns = False, *args, **kwargs) +@r_to_python +def betalactams(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.betalactams(*args, **kwargs) +@r_to_python +def betalactams_with_inhibitor(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.betalactams_with_inhibitor(only_sir_columns = False, *args, **kwargs) +@r_to_python +def carbapenems(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.carbapenems(*args, **kwargs) +@r_to_python +def cephalosporins(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.cephalosporins(*args, **kwargs) +@r_to_python +def cephalosporins_1st(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.cephalosporins_1st(only_sir_columns = False, *args, **kwargs) +@r_to_python +def cephalosporins_2nd(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.cephalosporins_2nd(only_sir_columns = False, *args, **kwargs) +@r_to_python +def cephalosporins_3rd(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.cephalosporins_3rd(*args, **kwargs) +@r_to_python +def cephalosporins_4th(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.cephalosporins_4th(only_sir_columns = False, *args, **kwargs) +@r_to_python +def cephalosporins_5th(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.cephalosporins_5th(only_sir_columns = False, *args, **kwargs) +@r_to_python +def fluoroquinolones(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.fluoroquinolones(*args, **kwargs) +@r_to_python +def glycopeptides(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.glycopeptides(only_sir_columns = False, *args, **kwargs) +@r_to_python +def ionophores(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ionophores(only_sir_columns = False, *args, **kwargs) +@r_to_python +def isoxazolylpenicillins(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.isoxazolylpenicillins(*args, **kwargs) +@r_to_python +def lincosamides(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.lincosamides(*args, **kwargs) +@r_to_python +def lipoglycopeptides(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.lipoglycopeptides(only_sir_columns = False, *args, **kwargs) +@r_to_python +def macrolides(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.macrolides(only_sir_columns = False, *args, **kwargs) +@r_to_python +def monobactams(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.monobactams(only_sir_columns = False, *args, **kwargs) +@r_to_python +def nitrofurans(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.nitrofurans(only_sir_columns = False, *args, **kwargs) +@r_to_python +def oxazolidinones(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.oxazolidinones(only_sir_columns = False, *args, **kwargs) +@r_to_python +def penicillins(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.penicillins(only_sir_columns = False, *args, **kwargs) +@r_to_python +def peptides(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.peptides(only_sir_columns = False, *args, **kwargs) +@r_to_python +def phenicols(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.phenicols(only_sir_columns = False, *args, **kwargs) +@r_to_python +def phosphonics(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.phosphonics(only_sir_columns = False, *args, **kwargs) +@r_to_python +def polymyxins(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.polymyxins(*args, **kwargs) +@r_to_python +def quinolones(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.quinolones(*args, **kwargs) +@r_to_python +def rifamycins(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.rifamycins(only_sir_columns = False, *args, **kwargs) +@r_to_python +def spiropyrimidinetriones(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.spiropyrimidinetriones(only_sir_columns = False, *args, **kwargs) +@r_to_python +def streptogramins(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.streptogramins(only_sir_columns = False, *args, **kwargs) +@r_to_python +def sulfonamides(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.sulfonamides(only_sir_columns = False, *args, **kwargs) +@r_to_python +def tetracyclines(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.tetracyclines(*args, **kwargs) +@r_to_python +def trimethoprims(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.trimethoprims(only_sir_columns = False, *args, **kwargs) +@r_to_python +def ureidopenicillins(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ureidopenicillins(only_sir_columns = False, *args, **kwargs) +@r_to_python +def amr_class(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.amr_class(*args, **kwargs) +@r_to_python +def amr_selector(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.amr_selector(*args, **kwargs) +@r_to_python +def administrable_per_os(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.administrable_per_os(only_sir_columns = False, *args, **kwargs) +@r_to_python +def administrable_iv(only_sir_columns = False, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.administrable_iv(only_sir_columns = False, *args, **kwargs) +@r_to_python +def not_intrinsic_resistant(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.not_intrinsic_resistant(*args, **kwargs) +@r_to_python +def as_ab(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.as_ab(*args, **kwargs) +@r_to_python +def is_ab(x): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.is_ab(x) +@r_to_python +def ab_reset_session(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ab_reset_session(*args, **kwargs) +@r_to_python +def as_av(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.as_av(x, *args, **kwargs) +@r_to_python +def is_av(x): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.is_av(x) +@r_to_python +def as_disk(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.as_disk(x, *args, **kwargs) +@r_to_python +def is_disk(x): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.is_disk(x) +@r_to_python +def as_mic(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.as_mic(x, *args, **kwargs) +@r_to_python +def is_mic(x): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.is_mic(x) +@r_to_python +def rescale_mic(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.rescale_mic(*args, **kwargs) +@r_to_python +def mic_p50(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mic_p50(x, *args, **kwargs) +@r_to_python +def mic_p90(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mic_p90(x, *args, **kwargs) +@r_to_python +def as_mo(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.as_mo(*args, **kwargs) +@r_to_python +def is_mo(x): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.is_mo(x) +@r_to_python +def mo_uncertainties(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_uncertainties(*args, **kwargs) +@r_to_python +def mo_renamed(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_renamed(*args, **kwargs) +@r_to_python +def mo_failures(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_failures(*args, **kwargs) +@r_to_python +def mo_reset_session(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_reset_session(*args, **kwargs) +@r_to_python +def mo_cleaning_regex(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_cleaning_regex(*args, **kwargs) +@r_to_python +def as_sir(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.as_sir(x, *args, **kwargs) +@r_to_python +def is_sir(x): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.is_sir(x) +@r_to_python +def is_sir_eligible(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.is_sir_eligible(x, *args, **kwargs) +@r_to_python +def sir_interpretation_history(clean): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.sir_interpretation_history(clean) +@r_to_python +def atc_online_property(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.atc_online_property(*args, **kwargs) +@r_to_python +def atc_online_groups(atc_code, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.atc_online_groups(atc_code, *args, **kwargs) +@r_to_python +def atc_online_ddd(atc_code, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.atc_online_ddd(atc_code, *args, **kwargs) +@r_to_python +def atc_online_ddd_units(atc_code, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.atc_online_ddd_units(atc_code, *args, **kwargs) +@r_to_python +def av_from_text(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.av_from_text(*args, **kwargs) +@r_to_python +def av_name(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.av_name(x, *args, **kwargs) +@r_to_python +def av_cid(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.av_cid(x, *args, **kwargs) +@r_to_python +def av_synonyms(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.av_synonyms(x, *args, **kwargs) +@r_to_python +def av_tradenames(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.av_tradenames(x, *args, **kwargs) +@r_to_python +def av_group(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.av_group(x, *args, **kwargs) +@r_to_python +def av_atc(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.av_atc(x, *args, **kwargs) +@r_to_python +def av_loinc(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.av_loinc(x, *args, **kwargs) +@r_to_python +def av_ddd(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.av_ddd(x, *args, **kwargs) +@r_to_python +def av_ddd_units(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.av_ddd_units(x, *args, **kwargs) +@r_to_python +def av_info(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.av_info(x, *args, **kwargs) +@r_to_python +def av_url(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.av_url(x, *args, **kwargs) +@r_to_python +def av_property(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.av_property(x, *args, **kwargs) +@r_to_python +def availability(tbl, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.availability(tbl, *args, **kwargs) +@r_to_python +def bug_drug_combinations(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.bug_drug_combinations(*args, **kwargs) +@r_to_python +def count_resistant(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.count_resistant(*args, **kwargs) +@r_to_python +def count_susceptible(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.count_susceptible(*args, **kwargs) +@r_to_python +def count_S(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.count_S(*args, **kwargs) +@r_to_python +def count_SI(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.count_SI(*args, **kwargs) +@r_to_python +def count_I(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.count_I(*args, **kwargs) +@r_to_python +def count_IR(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.count_IR(*args, **kwargs) +@r_to_python +def count_R(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.count_R(*args, **kwargs) +@r_to_python +def count_all(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.count_all(*args, **kwargs) +@r_to_python +def n_sir(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.n_sir(*args, **kwargs) +@r_to_python +def count_df(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.count_df(*args, **kwargs) +@r_to_python +def custom_interpretive_rules(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.custom_interpretive_rules(*args, **kwargs) +@r_to_python +def custom_mdro_guideline(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.custom_mdro_guideline(*args, **kwargs) +@r_to_python +def export_ncbi_biosample(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.export_ncbi_biosample(*args, **kwargs) +@r_to_python +def first_isolate(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.first_isolate(*args, **kwargs) +@r_to_python +def filter_first_isolate(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.filter_first_isolate(*args, **kwargs) +@r_to_python +def g_test(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.g_test(x, *args, **kwargs) +@r_to_python +def is_new_episode(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.is_new_episode(x, *args, **kwargs) +@r_to_python +def ggplot_pca(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ggplot_pca(*args, **kwargs) +@r_to_python +def ggplot_sir(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ggplot_sir(*args, **kwargs) +@r_to_python +def geom_sir(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.geom_sir(*args, **kwargs) +@r_to_python +def guess_ab_col(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.guess_ab_col(*args, **kwargs) +@r_to_python +def interpretive_rules(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.interpretive_rules(*args, **kwargs) +@r_to_python +def eucast_rules(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.eucast_rules(*args, **kwargs) +@r_to_python +def clsi_rules(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.clsi_rules(*args, **kwargs) +@r_to_python +def eucast_dosage(ab, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.eucast_dosage(ab, *args, **kwargs) +@r_to_python +def italicise_taxonomy(string, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.italicise_taxonomy(string, *args, **kwargs) +@r_to_python +def italicize_taxonomy(string, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.italicize_taxonomy(string, *args, **kwargs) +@r_to_python +def inner_join_microorganisms(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.inner_join_microorganisms(x, *args, **kwargs) +@r_to_python +def left_join_microorganisms(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.left_join_microorganisms(x, *args, **kwargs) +@r_to_python +def right_join_microorganisms(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.right_join_microorganisms(x, *args, **kwargs) +@r_to_python +def full_join_microorganisms(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.full_join_microorganisms(x, *args, **kwargs) +@r_to_python +def semi_join_microorganisms(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.semi_join_microorganisms(x, *args, **kwargs) +@r_to_python +def anti_join_microorganisms(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.anti_join_microorganisms(x, *args, **kwargs) +@r_to_python +def key_antimicrobials(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.key_antimicrobials(*args, **kwargs) +@r_to_python +def all_antimicrobials(x = None, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.all_antimicrobials(x = None, *args, **kwargs) +@r_to_python +def kurtosis(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.kurtosis(x, *args, **kwargs) +@r_to_python +def like(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.like(x, *args, **kwargs) +@r_to_python +def mdro(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mdro(*args, **kwargs) +@r_to_python +def brmo(x = None, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.brmo(x = None, *args, **kwargs) +@r_to_python +def mrgn(x = None, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mrgn(x = None, *args, **kwargs) +@r_to_python +def mdr_tb(x = None, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mdr_tb(x = None, *args, **kwargs) +@r_to_python +def mdr_cmi2012(x = None, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mdr_cmi2012(x = None, *args, **kwargs) +@r_to_python +def eucast_exceptional_phenotypes(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.eucast_exceptional_phenotypes(*args, **kwargs) +@r_to_python +def mean_amr_distance(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mean_amr_distance(x, *args, **kwargs) +@r_to_python +def amr_distance_from_row(amr_distance, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.amr_distance_from_row(amr_distance, *args, **kwargs) +@r_to_python +def mo_matching_score(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_matching_score(x, *args, **kwargs) +@r_to_python +def mo_name(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_name(*args, **kwargs) +@r_to_python +def mo_fullname(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_fullname(*args, **kwargs) +@r_to_python +def mo_shortname(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_shortname(*args, **kwargs) +@r_to_python +def mo_subspecies(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_subspecies(*args, **kwargs) +@r_to_python +def mo_species(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_species(*args, **kwargs) +@r_to_python +def mo_genus(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_genus(*args, **kwargs) +@r_to_python +def mo_family(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_family(*args, **kwargs) +@r_to_python +def mo_order(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_order(*args, **kwargs) +@r_to_python +def mo_class(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_class(*args, **kwargs) +@r_to_python +def mo_phylum(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_phylum(*args, **kwargs) +@r_to_python +def mo_kingdom(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_kingdom(*args, **kwargs) +@r_to_python +def mo_domain(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_domain(*args, **kwargs) +@r_to_python +def mo_type(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_type(*args, **kwargs) +@r_to_python +def mo_status(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_status(*args, **kwargs) +@r_to_python +def mo_pathogenicity(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_pathogenicity(*args, **kwargs) +@r_to_python +def mo_gramstain(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_gramstain(*args, **kwargs) +@r_to_python +def mo_is_gram_negative(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_is_gram_negative(*args, **kwargs) +@r_to_python +def mo_is_gram_positive(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_is_gram_positive(*args, **kwargs) +@r_to_python +def mo_is_yeast(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_is_yeast(*args, **kwargs) +@r_to_python +def mo_is_intrinsic_resistant(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_is_intrinsic_resistant(*args, **kwargs) +@r_to_python +def mo_oxygen_tolerance(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_oxygen_tolerance(*args, **kwargs) +@r_to_python +def mo_is_anaerobic(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_is_anaerobic(*args, **kwargs) +@r_to_python +def mo_morphology(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_morphology(*args, **kwargs) +@r_to_python +def mo_snomed(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_snomed(*args, **kwargs) +@r_to_python +def mo_ref(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_ref(*args, **kwargs) +@r_to_python +def mo_authors(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_authors(*args, **kwargs) +@r_to_python +def mo_year(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_year(*args, **kwargs) +@r_to_python +def mo_lpsn(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_lpsn(*args, **kwargs) +@r_to_python +def mo_mycobank(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_mycobank(*args, **kwargs) +@r_to_python +def mo_gbif(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_gbif(*args, **kwargs) +@r_to_python +def mo_rank(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_rank(*args, **kwargs) +@r_to_python +def mo_taxonomy(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_taxonomy(*args, **kwargs) +@r_to_python +def mo_synonyms(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_synonyms(*args, **kwargs) +@r_to_python +def mo_current(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_current(x, *args, **kwargs) +@r_to_python +def mo_group_members(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_group_members(*args, **kwargs) +@r_to_python +def mo_info(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_info(*args, **kwargs) +@r_to_python +def mo_url(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_url(*args, **kwargs) +@r_to_python +def mo_property(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.mo_property(*args, **kwargs) +@r_to_python +def pca(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.pca(*args, **kwargs) +@r_to_python +def theme_sir(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.theme_sir(*args, **kwargs) +@r_to_python +def labels_sir_count(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.labels_sir_count(*args, **kwargs) +@r_to_python +def resistance(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.resistance(*args, **kwargs) +@r_to_python +def susceptibility(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.susceptibility(*args, **kwargs) +@r_to_python +def sir_confidence_interval(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.sir_confidence_interval(*args, **kwargs) +@r_to_python +def proportion_R(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.proportion_R(*args, **kwargs) +@r_to_python +def proportion_IR(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.proportion_IR(*args, **kwargs) +@r_to_python +def proportion_I(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.proportion_I(*args, **kwargs) +@r_to_python +def proportion_SI(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.proportion_SI(*args, **kwargs) +@r_to_python +def proportion_S(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.proportion_S(*args, **kwargs) +@r_to_python +def proportion_df(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.proportion_df(*args, **kwargs) +@r_to_python +def sir_df(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.sir_df(*args, **kwargs) +@r_to_python +def random_mic(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.random_mic(*args, **kwargs) +@r_to_python +def random_disk(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.random_disk(*args, **kwargs) +@r_to_python +def random_sir(size = None, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.random_sir(size = None, *args, **kwargs) +@r_to_python +def resistance_predict(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.resistance_predict(*args, **kwargs) +@r_to_python +def sir_predict(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.sir_predict(*args, **kwargs) +@r_to_python +def ggplot_sir_predict(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.ggplot_sir_predict(*args, **kwargs) +@r_to_python +def skewness(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.skewness(x, *args, **kwargs) +@r_to_python +def top_n_microorganisms(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.top_n_microorganisms(*args, **kwargs) +@r_to_python +def reset_AMR_locale(*args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.reset_AMR_locale(*args, **kwargs) +@r_to_python +def translate_AMR(x, *args, **kwargs): + """Please see our website of the R package for the full manual: https://amr-for-r.org""" + return amr_r.translate_AMR(x, *args, **kwargs) diff --git a/README.md b/README.md new file mode 100755 index 000000000..0e944d21f --- /dev/null +++ b/README.md @@ -0,0 +1,226 @@ + +The `AMR` package for R is a powerful tool for antimicrobial resistance (AMR) analysis. It provides extensive features for handling microbial and antimicrobial data. However, for those who work primarily in Python, we now have a more intuitive option available: the [`AMR` Python package](https://pypi.org/project/AMR/). + +This Python package is a wrapper around the `AMR` R package. It uses the `rpy2` package internally. Despite the need to have R installed, Python users can now easily work with AMR data directly through Python code. + +# Prerequisites + +This package was only tested with a [virtual environment (venv)](https://docs.python.org/3/library/venv.html). You can set up such an environment by running: + +```python +# linux and macOS: +python -m venv /path/to/new/virtual/environment + +# Windows: +python -m venv C:\path\to\new\virtual\environment +``` + +Then you can [activate the environment](https://docs.python.org/3/library/venv.html#how-venvs-work), after which the venv is ready to work with. + +# Install AMR + +1. Since the Python package is available on the official [Python Package Index](https://pypi.org/project/AMR/), you can just run: + + ```bash + pip install AMR + ``` + +2. Make sure you have R installed. There is **no need to install the `AMR` R package**, as it will be installed automatically. + + For Linux: + + ```bash + # Ubuntu / Debian + sudo apt install r-base + # Fedora: + sudo dnf install R + # CentOS/RHEL + sudo yum install R + ``` + + For macOS (using [Homebrew](https://brew.sh)): + + ```bash + brew install r + ``` + + For Windows, visit the [CRAN download page](https://cran.r-project.org) to download and install R. + +# Examples of Usage + +## Cleaning Taxonomy + +Here’s an example that demonstrates how to clean microorganism and drug names using the `AMR` Python package: + +```python +import pandas as pd +import AMR + +# Sample data +data = { + "MOs": ['E. coli', 'ESCCOL', 'esco', 'Esche coli'], + "Drug": ['Cipro', 'CIP', 'J01MA02', 'Ciproxin'] +} +df = pd.DataFrame(data) + +# Use AMR functions to clean microorganism and drug names +df['MO_clean'] = AMR.mo_name(df['MOs']) +df['Drug_clean'] = AMR.ab_name(df['Drug']) + +# Display the results +print(df) +``` + +| MOs | Drug | MO_clean | Drug_clean | +|-------------|-----------|--------------------|---------------| +| E. coli | Cipro | Escherichia coli | Ciprofloxacin | +| ESCCOL | CIP | Escherichia coli | Ciprofloxacin | +| esco | J01MA02 | Escherichia coli | Ciprofloxacin | +| Esche coli | Ciproxin | Escherichia coli | Ciprofloxacin | + +### Explanation + +* **mo_name:** This function standardises microorganism names. Here, different variations of *Escherichia coli* (such as "E. coli", "ESCCOL", "esco", and "Esche coli") are all converted into the correct, standardised form, "Escherichia coli". + +* **ab_name**: Similarly, this function standardises antimicrobial names. The different representations of ciprofloxacin (e.g., "Cipro", "CIP", "J01MA02", and "Ciproxin") are all converted to the standard name, "Ciprofloxacin". + +## Calculating AMR + +```python +import AMR +import pandas as pd + +df = AMR.example_isolates +result = AMR.resistance(df["AMX"]) +print(result) +``` + +``` +[0.59555556] +``` + +## Generating Antibiograms + +One of the core functions of the `AMR` package is generating an antibiogram, a table that summarises the antimicrobial susceptibility of bacterial isolates. Here’s how you can generate an antibiogram from Python: + +```python +result2a = AMR.antibiogram(df[["mo", "AMX", "CIP", "TZP"]]) +print(result2a) +``` + +| Pathogen | Amoxicillin | Ciprofloxacin | Piperacillin/tazobactam | +|-----------------|-----------------|-----------------|--------------------------| +| CoNS | 7% (10/142) | 73% (183/252) | 30% (10/33) | +| E. coli | 50% (196/392) | 88% (399/456) | 94% (393/416) | +| K. pneumoniae | 0% (0/58) | 96% (53/55) | 89% (47/53) | +| P. aeruginosa | 0% (0/30) | 100% (30/30) | None | +| P. mirabilis | None | 94% (34/36) | None | +| S. aureus | 6% (8/131) | 90% (171/191) | None | +| S. epidermidis | 1% (1/91) | 64% (87/136) | None | +| S. hominis | None | 80% (56/70) | None | +| S. pneumoniae | 100% (112/112) | None | 100% (112/112) | + + +```python +result2b = AMR.antibiogram(df[["mo", "AMX", "CIP", "TZP"]], mo_transform = "gramstain") +print(result2b) +``` + +| Pathogen | Amoxicillin | Ciprofloxacin | Piperacillin/tazobactam | +|----------------|-----------------|------------------|--------------------------| +| Gram-negative | 36% (226/631) | 91% (621/684) | 88% (565/641) | +| Gram-positive | 43% (305/703) | 77% (560/724) | 86% (296/345) | + + +In this example, we generate an antibiogram by selecting various antibiotics. + +## Taxonomic Data Sets Now in Python! + +As a Python user, you might like that the most important data sets of the `AMR` R package, `microorganisms`, `antimicrobials`, `clinical_breakpoints`, and `example_isolates`, are now available as regular Python data frames: + +```python +AMR.microorganisms +``` + +| mo | fullname | status | kingdom | gbif | gbif_parent | gbif_renamed_to | prevalence | +|--------------|------------------------------------|----------|----------|-----------|-------------|-----------------|------------| +| B_GRAMN | (unknown Gram-negatives) | unknown | Bacteria | None | None | None | 2.0 | +| B_GRAMP | (unknown Gram-positives) | unknown | Bacteria | None | None | None | 2.0 | +| B_ANAER-NEG | (unknown anaerobic Gram-negatives) | unknown | Bacteria | None | None | None | 2.0 | +| B_ANAER-POS | (unknown anaerobic Gram-positives) | unknown | Bacteria | None | None | None | 2.0 | +| B_ANAER | (unknown anaerobic bacteria) | unknown | Bacteria | None | None | None | 2.0 | +| ... | ... | ... | ... | ... | ... | ... | ... | +| B_ZYMMN_POMC | Zymomonas pomaceae | accepted | Bacteria | 10744418 | 3221412 | None | 2.0 | +| B_ZYMPH | Zymophilus | synonym | Bacteria | None | 9475166 | None | 2.0 | +| B_ZYMPH_PCVR | Zymophilus paucivorans | synonym | Bacteria | None | None | None | 2.0 | +| B_ZYMPH_RFFN | Zymophilus raffinosivorans | synonym | Bacteria | None | None | None | 2.0 | +| F_ZYZYG | Zyzygomyces | unknown | Fungi | None | 7581 | None | 2.0 | + +```python +AMR.antimicrobials +``` + +| ab | cid | name | group | oral_ddd | oral_units | iv_ddd | iv_units | +|-----|-------------|----------------------|----------------------------|----------|------------|--------|----------| +| AMA | 4649.0 | 4-aminosalicylic acid| Antimycobacterials | 12.00 | g | NaN | None | +| ACM | 6450012.0 | Acetylmidecamycin | Macrolides/lincosamides | NaN | None | NaN | None | +| ASP | 49787020.0 | Acetylspiramycin | Macrolides/lincosamides | NaN | None | NaN | None | +| ALS | 8954.0 | Aldesulfone sodium | Other antibacterials | 0.33 | g | NaN | None | +| AMK | 37768.0 | Amikacin | Aminoglycosides | NaN | None | 1.0 | g | +| ... | ... | ... | ... | ... | ... | ... | ... | +| VIR | 11979535.0 | Virginiamycine | Other antibacterials | NaN | None | NaN | None | +| VOR | 71616.0 | Voriconazole | Antifungals/antimycotics | 0.40 | g | 0.4 | g | +| XBR | 72144.0 | Xibornol | Other antibacterials | NaN | None | NaN | None | +| ZID | 77846445.0 | Zidebactam | Other antibacterials | NaN | None | NaN | None | +| ZFD | NaN | Zoliflodacin | None | NaN | None | NaN | None | + + +# Installation Channels + +## Stable Release (CRAN) + +The default `AMR` Python package uses the latest stable version of the `AMR` R package, published on CRAN. After running `pip install AMR`, import it as usual: + +```python +import AMR + +AMR.example_isolates +``` + +## Development Version (GitHub) + +To use the latest development version of the `AMR` R package (sourced directly from GitHub), import the `beta` sub-package and alias it as `AMR`: + +```python +import AMR.beta as AMR + +AMR.example_isolates +``` + +Aliasing with `as AMR` keeps all downstream code identical to the stable import. Switching between the stable release and the development version requires changing only the import line — nothing else in your script needs to change. + +# SIR Classification with `as_sir()` + +## Using `enforce_method` + +The `as_sir()` function in R uses S3 method dispatch to select the correct calculation method based on the input class: `` for MIC values and `` for disk diffusion values. Because Python objects do not carry R class attributes through the `rpy2` bridge, this automatic dispatch may not resolve correctly. + +To explicitly specify the input type, use the `enforce_method` argument: + +```python +# Treat the column as MIC values — maps to R's as.sir.mic() +AMR.as_sir(df["MIC_col"], mo="E. coli", ab="AMX", guideline="EUCAST", enforce_method="mic") + +# Treat the column as disk diffusion values — maps to R's as.sir.disk() +AMR.as_sir(df["disk_col"], mo="E. coli", ab="AMX", guideline="EUCAST", enforce_method="disk") +``` + +Without `enforce_method`, R falls back to class-based dispatch on the raw Python input, which may fail or return unexpected results. Always supply `enforce_method` when calling `as_sir()` from Python. + +# Conclusion + +With the `AMR` Python package, Python users can now effortlessly call R functions from the `AMR` R package. This eliminates the need for complex `rpy2` configurations and provides a clean, easy-to-use interface for antimicrobial resistance analysis. The examples provided above demonstrate how this can be applied to typical workflows, such as standardising microorganism and antimicrobial names or calculating resistance. + +By just running `import AMR`, users can seamlessly integrate the robust features of the R `AMR` package into Python workflows. + +Whether you're cleaning data or analysing resistance patterns, the `AMR` Python package makes it easy to work with AMR data in Python. diff --git a/dist/amr-3.0.1.9078-py3-none-any.whl b/dist/amr-3.0.1.9078-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..7f051225b24b48b691f546ac7d73034bc0fe8f32 GIT binary patch literal 13407 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 bT{ZAr@vHKGgBeZW8|c!4&L0dG0QNrsL%N}K literal 0 HcmV?d00001 diff --git a/setup.py b/setup.py new file mode 100644 index 000000000..995701f3b --- /dev/null +++ b/setup.py @@ -0,0 +1,27 @@ +from setuptools import setup, find_packages + +setup( + name='AMR', + version='3.0.1.9078', + packages=find_packages(), + install_requires=[ + 'rpy2', + 'numpy', + 'pandas', + ], + author='Matthijs Berends', + author_email='m.s.berends@umcg.nl', + description='A Python wrapper for the AMR R package', + long_description=open('README.md').read(), + long_description_content_type='text/markdown', + url='https://github.com/msberends/AMR', + project_urls={ + 'Bug Tracker': 'https://github.com/msberends/AMR/issues', + }, + license='GPL 2', + classifiers=[ + 'Programming Language :: Python :: 3', + 'Operating System :: OS Independent', + ], + python_requires='>=3.6', +)