mirror of
https://github.com/msberends/AMR.git
synced 2025-07-21 17:33:14 +02:00
(v3.0.0.9012) Python wrapper fix
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
Package: AMR
|
Package: AMR
|
||||||
Version: 3.0.0.9011
|
Version: 3.0.0.9012
|
||||||
Date: 2025-07-17
|
Date: 2025-07-17
|
||||||
Title: Antimicrobial Resistance Data Analysis
|
Title: Antimicrobial Resistance Data Analysis
|
||||||
Description: Functions to simplify and standardise antimicrobial resistance (AMR)
|
Description: Functions to simplify and standardise antimicrobial resistance (AMR)
|
||||||
|
2
NEWS.md
2
NEWS.md
@ -1,4 +1,4 @@
|
|||||||
# AMR 3.0.0.9011
|
# AMR 3.0.0.9012
|
||||||
|
|
||||||
This is primarily a bugfix release, though we added one nice feature too.
|
This is primarily a bugfix release, though we added one nice feature too.
|
||||||
|
|
||||||
|
@ -56,7 +56,8 @@ os.makedirs(r_lib_path, exist_ok=True)
|
|||||||
os.environ['R_LIBS_SITE'] = r_lib_path
|
os.environ['R_LIBS_SITE'] = r_lib_path
|
||||||
|
|
||||||
from rpy2 import robjects
|
from rpy2 import robjects
|
||||||
from rpy2.robjects import pandas2ri
|
from rpy2.robjects.conversion import localconverter
|
||||||
|
from rpy2.robjects import default_converter, numpy2ri, pandas2ri
|
||||||
from rpy2.robjects.packages import importr, isinstalled
|
from rpy2.robjects.packages import importr, isinstalled
|
||||||
|
|
||||||
# Import base and utils
|
# Import base and utils
|
||||||
@ -94,10 +95,9 @@ if r_amr_version != python_amr_version:
|
|||||||
print(f"AMR: Setting up R environment and AMR datasets...", flush=True)
|
print(f"AMR: Setting up R environment and AMR datasets...", flush=True)
|
||||||
|
|
||||||
# Activate the automatic conversion between R and pandas DataFrames
|
# Activate the automatic conversion between R and pandas DataFrames
|
||||||
pandas2ri.activate()
|
with localconverter(default_converter + numpy2ri.converter + pandas2ri.converter):
|
||||||
|
|
||||||
# example_isolates
|
# example_isolates
|
||||||
example_isolates = pandas2ri.rpy2py(robjects.r('''
|
example_isolates = robjects.r('''
|
||||||
df <- AMR::example_isolates
|
df <- AMR::example_isolates
|
||||||
df[] <- lapply(df, function(x) {
|
df[] <- lapply(df, function(x) {
|
||||||
if (inherits(x, c("Date", "POSIXt", "factor"))) {
|
if (inherits(x, c("Date", "POSIXt", "factor"))) {
|
||||||
@ -108,13 +108,13 @@ df[] <- lapply(df, function(x) {
|
|||||||
})
|
})
|
||||||
df <- df[, !sapply(df, is.list)]
|
df <- df[, !sapply(df, is.list)]
|
||||||
df
|
df
|
||||||
'''))
|
''')
|
||||||
example_isolates['date'] = pd.to_datetime(example_isolates['date'])
|
example_isolates['date'] = pd.to_datetime(example_isolates['date'])
|
||||||
|
|
||||||
# microorganisms
|
# microorganisms
|
||||||
microorganisms = pandas2ri.rpy2py(robjects.r('AMR::microorganisms[, !sapply(AMR::microorganisms, is.list)]'))
|
microorganisms = robjects.r('AMR::microorganisms[, !sapply(AMR::microorganisms, is.list)]')
|
||||||
antimicrobials = pandas2ri.rpy2py(robjects.r('AMR::antimicrobials[, !sapply(AMR::antimicrobials, is.list)]'))
|
antimicrobials = robjects.r('AMR::antimicrobials[, !sapply(AMR::antimicrobials, is.list)]')
|
||||||
clinical_breakpoints = pandas2ri.rpy2py(robjects.r('AMR::clinical_breakpoints[, !sapply(AMR::clinical_breakpoints, is.list)]'))
|
clinical_breakpoints = robjects.r('AMR::clinical_breakpoints[, !sapply(AMR::clinical_breakpoints, is.list)]')
|
||||||
|
|
||||||
base.options(warn = 0)
|
base.options(warn = 0)
|
||||||
|
|
||||||
@ -129,16 +129,15 @@ echo "from .datasets import clinical_breakpoints" >> $init_file
|
|||||||
|
|
||||||
# Write header to the functions Python file, including the convert_to_python function
|
# Write header to the functions Python file, including the convert_to_python function
|
||||||
cat <<EOL > "$functions_file"
|
cat <<EOL > "$functions_file"
|
||||||
|
import functools
|
||||||
import rpy2.robjects as robjects
|
import rpy2.robjects as robjects
|
||||||
from rpy2.robjects.packages import importr
|
from rpy2.robjects.packages import importr
|
||||||
from rpy2.robjects.vectors import StrVector, FactorVector, IntVector, FloatVector, DataFrame
|
from rpy2.robjects.vectors import StrVector, FactorVector, IntVector, FloatVector, DataFrame
|
||||||
from rpy2.robjects import pandas2ri
|
from rpy2.robjects.conversion import localconverter
|
||||||
|
from rpy2.robjects import default_converter, numpy2ri, pandas2ri
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
# Activate automatic conversion between R data frames and pandas data frames
|
|
||||||
pandas2ri.activate()
|
|
||||||
|
|
||||||
# Import the AMR R package
|
# Import the AMR R package
|
||||||
amr_r = importr('AMR')
|
amr_r = importr('AMR')
|
||||||
|
|
||||||
@ -156,10 +155,8 @@ def convert_to_python(r_output):
|
|||||||
return list(r_output) # Convert to a Python list of integers or floats
|
return list(r_output) # Convert to a Python list of integers or floats
|
||||||
|
|
||||||
# Check if it's a pandas-compatible R data frame
|
# Check if it's a pandas-compatible R data frame
|
||||||
elif isinstance(r_output, pd.DataFrame):
|
elif isinstance(r_output, (pd.DataFrame, DataFrame)):
|
||||||
return r_output # Return as pandas DataFrame (already converted by pandas2ri)
|
return r_output # Return as pandas DataFrame (already converted by pandas2ri)
|
||||||
elif isinstance(r_output, DataFrame):
|
|
||||||
return pandas2ri.rpy2py(r_output) # Return as pandas DataFrame
|
|
||||||
|
|
||||||
# Check if the input is a NumPy array and has a string data type
|
# 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_):
|
if isinstance(r_output, np.ndarray) and np.issubdtype(r_output.dtype, np.str_):
|
||||||
@ -167,6 +164,15 @@ def convert_to_python(r_output):
|
|||||||
|
|
||||||
# Fall-back
|
# Fall-back
|
||||||
return r_output
|
return r_output
|
||||||
|
|
||||||
|
def r_to_python(r_func):
|
||||||
|
"""Decorator that runs an rpy2 function under a localconverter
|
||||||
|
and then applies convert_to_python to its output."""
|
||||||
|
@functools.wraps(r_func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
with localconverter(default_converter + numpy2ri.converter + pandas2ri.converter):
|
||||||
|
return convert_to_python(r_func(*args, **kwargs))
|
||||||
|
return wrapper
|
||||||
EOL
|
EOL
|
||||||
|
|
||||||
# Directory where the .Rd files are stored (update path as needed)
|
# Directory where the .Rd files are stored (update path as needed)
|
||||||
@ -246,10 +252,11 @@ for rd_file in "$rd_dir"/*.Rd; do
|
|||||||
gsub("FALSE", "False", func_args)
|
gsub("FALSE", "False", func_args)
|
||||||
gsub("NULL", "None", func_args)
|
gsub("NULL", "None", func_args)
|
||||||
|
|
||||||
# Write the Python function definition to the output file
|
# Write the Python function definition to the output file, using decorator
|
||||||
|
print "@r_to_python" >> "'"$functions_file"'"
|
||||||
print "def " func_name_py "(" func_args "):" >> "'"$functions_file"'"
|
print "def " func_name_py "(" func_args "):" >> "'"$functions_file"'"
|
||||||
print " \"\"\"Please see our website of the R package for the full manual: https://amr-for-r.org\"\"\"" >> "'"$functions_file"'"
|
print " \"\"\"Please see our website of the R package for the full manual: https://amr-for-r.org\"\"\"" >> "'"$functions_file"'"
|
||||||
print " return convert_to_python(amr_r." func_name_py "(" func_args "))" >> "'"$functions_file"'"
|
print " return amr_r." func_name_py "(" func_args ")" >> "'"$functions_file"'"
|
||||||
|
|
||||||
print "from .functions import " func_name_py >> "'"$init_file"'"
|
print "from .functions import " func_name_py >> "'"$init_file"'"
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user