From 187990f5d7b683b6c4690fc20ec6bba8990a5bef Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 13 Aug 2026 09:16:43 +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.9086-py3-none-any.whl | Bin 0 -> 13406 bytes dist/amr-3.0.1.9086.tar.gz | Bin 0 -> 12634 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.9086-py3-none-any.whl create mode 100644 dist/amr-3.0.1.9086.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..5eab1af83 --- /dev/null +++ b/AMR.egg-info/PKG-INFO @@ -0,0 +1,254 @@ +Metadata-Version: 2.4 +Name: AMR +Version: 3.0.1.9086 +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.9086-py3-none-any.whl b/dist/amr-3.0.1.9086-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..3965f8f07b30ded7feee97c4db59d151dbabf8e6 GIT binary patch literal 13406 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 literal 0 HcmV?d00001 diff --git a/setup.py b/setup.py new file mode 100644 index 000000000..d98818074 --- /dev/null +++ b/setup.py @@ -0,0 +1,27 @@ +from setuptools import setup, find_packages + +setup( + name='AMR', + version='3.0.1.9086', + 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', +)