From 4a911b301c41e32963009eb58475cec9e6c676c8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 26 Jun 2026 10:06:56 +0000 Subject: [PATCH] Python wrapper update --- AMR.egg-info/PKG-INFO | 212 ++++++ 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 | 184 +++++ dist/amr-3.0.1.9075-py3-none-any.whl | Bin 0 -> 12719 bytes dist/amr-3.0.1.9075.tar.gz | Bin 0 -> 11948 bytes setup.py | 27 + 14 files changed, 1842 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.9075-py3-none-any.whl create mode 100644 dist/amr-3.0.1.9075.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..0458f7efb --- /dev/null +++ b/AMR.egg-info/PKG-INFO @@ -0,0 +1,212 @@ +Metadata-Version: 2.4 +Name: AMR +Version: 3.0.1.9075 +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 | + + +# 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..43aa015bd --- /dev/null +++ b/README.md @@ -0,0 +1,184 @@ + +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 | + + +# 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.9075-py3-none-any.whl b/dist/amr-3.0.1.9075-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..c1991085577650d055753d1b0841fa076eb1c5ce GIT binary patch literal 12719 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 BlJEck literal 0 HcmV?d00001 diff --git a/setup.py b/setup.py new file mode 100644 index 000000000..bb8aa7c5d --- /dev/null +++ b/setup.py @@ -0,0 +1,27 @@ +from setuptools import setup, find_packages + +setup( + name='AMR', + version='3.0.1.9075', + 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', +)