From 050bd4d2a2333df937cd9c41c571b03bc3b32ce4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 3 Jul 2026 17:42:38 +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.9083-py3-none-any.whl | Bin 0 -> 13408 bytes dist/amr-3.0.1.9083.tar.gz | Bin 0 -> 12656 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.9083-py3-none-any.whl create mode 100644 dist/amr-3.0.1.9083.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..3c05205a1 --- /dev/null +++ b/AMR.egg-info/PKG-INFO @@ -0,0 +1,254 @@ +Metadata-Version: 2.4 +Name: AMR +Version: 3.0.1.9083 +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.9083-py3-none-any.whl b/dist/amr-3.0.1.9083-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..0c7de2cdf9f3527fcc378eb9a57e6b99cbff3ec5 GIT binary patch literal 13408 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 literal 0 HcmV?d00001 diff --git a/setup.py b/setup.py new file mode 100644 index 000000000..5779cad18 --- /dev/null +++ b/setup.py @@ -0,0 +1,27 @@ +from setuptools import setup, find_packages + +setup( + name='AMR', + version='3.0.1.9083', + 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', +)