From 53b392fbab3dae96e8b853574330425a95fe9ac7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 27 Jun 2026 13:34:14 +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.9081-py3-none-any.whl | Bin 0 -> 13407 bytes dist/amr-3.0.1.9081.tar.gz | Bin 0 -> 12645 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.9081-py3-none-any.whl create mode 100644 dist/amr-3.0.1.9081.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..72326cee4 --- /dev/null +++ b/AMR.egg-info/PKG-INFO @@ -0,0 +1,254 @@ +Metadata-Version: 2.4 +Name: AMR +Version: 3.0.1.9081 +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.9081-py3-none-any.whl b/dist/amr-3.0.1.9081-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..67cee04f8bcc31b6c03b26aacd070c08245dba9b GIT binary patch literal 13407 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 B+a3S_ literal 0 HcmV?d00001 diff --git a/dist/amr-3.0.1.9081.tar.gz b/dist/amr-3.0.1.9081.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..754020c450132bc931b205ceaef98a9a8f95238a GIT binary patch literal 12645 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