From c3bbc8f725bab78fed98d90ba7a9eaa3f986af78 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 4 Sep 2026 17:49:11 +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.9090-py3-none-any.whl | Bin 0 -> 13408 bytes dist/amr-3.0.1.9090.tar.gz | Bin 0 -> 12643 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.9090-py3-none-any.whl create mode 100644 dist/amr-3.0.1.9090.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..c7ff7b761 --- /dev/null +++ b/AMR.egg-info/PKG-INFO @@ -0,0 +1,254 @@ +Metadata-Version: 2.4 +Name: AMR +Version: 3.0.1.9090 +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.9090-py3-none-any.whl b/dist/amr-3.0.1.9090-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..3f93ae19813bbbef9ae54922b46cc8ee36f69d91 GIT binary patch literal 13408 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�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 E7qF_YNdN!< literal 0 HcmV?d00001 diff --git a/setup.py b/setup.py new file mode 100644 index 000000000..e02f26e31 --- /dev/null +++ b/setup.py @@ -0,0 +1,27 @@ +from setuptools import setup, find_packages + +setup( + name='AMR', + version='3.0.1.9090', + 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', +)