Python interface to the R language (embedded R)
—
Import and manage R packages from Python with automatic function signature translation, Python-style calling conventions, and seamless integration with the R package ecosystem.
Import R packages into Python namespace with automatic function wrapping and signature translation.
def importr(name: str, lib_loc=None, robject_translations={},
signature_translation: bool = True, suppress_messages: bool = True,
on_conflict: str = 'fail', symbol_r2python=None,
symbol_resolve=None, data: bool = True) -> Package:
"""
Import R package and return Python wrapper.
Parameters:
- name: R package name to import
- lib_loc: Library location (default: R default library paths)
- robject_translations: Dictionary mapping R names to Python names
- signature_translation: Enable Python-style function signatures
- suppress_messages: Suppress R package loading messages
- on_conflict: Action on naming conflicts ('fail', 'warn', 'resolve')
- symbol_r2python: Function to convert R symbols to Python names
- symbol_resolve: Function to resolve naming conflicts
- data: Import package datasets
Returns:
Package wrapper with Python-accessible R functions
Raises:
PackageNotInstalledError: If R package is not installed or cannot be loaded
"""Check if R packages are installed and accessible.
def isinstalled(name: str, lib_loc=None) -> bool:
"""
Check if R package is installed.
Parameters:
- name: R package name to check
- lib_loc: Library location to search (default: R default library paths)
Returns:
True if package is installed and loadable
"""
def quiet_require(name: str, lib_loc=None) -> bool:
"""
Load an R package quietly (suppressing messages).
Parameters:
- name: R package name to load
- lib_loc: Library location (default: R default library paths)
Returns:
True if package loaded successfully
"""For package installation, removal, and management, use R commands directly through rpy2's R interface.
# Package installation (via R)
# r('install.packages("package_name")')
# r('install.packages(c("pkg1", "pkg2"))')
# Package removal (via R)
# r('remove.packages("package_name")')
# Check installed packages (via R)
# r('installed.packages()')
# Update packages (via R)
# r('update.packages()')Different types of package wrappers providing various levels of Python integration.
class Package(ModuleType):
"""
Basic R package wrapper with direct function access.
Provides access to R package functions through Python
attribute access with minimal signature translation.
"""
def __getattr__(self, name: str): ...
@property
def __rdata__(self) -> 'PackageData': ...
class SignatureTranslatedPackage(Package):
"""
Package wrapper with Python-style function signatures.
Translates R parameter names to Python conventions and
provides more Pythonic calling patterns.
"""
class InstalledPackage(Package):
"""
Wrapper for installed R package with metadata access.
Provides information about installed packages including
version, dependencies, and description.
"""
@property
def version(self) -> str: ...
@property
def description(self) -> str: ...
class InstalledSTPackage(InstalledPackage):
"""
Installed package wrapper with signature translation.
Combines installed package metadata with signature
translation for enhanced Python integration.
"""
class WeakPackage(Package):
"""
Weak reference package wrapper for memory management.
Holds weak references to R package objects to prevent
memory leaks in long-running applications.
"""Classes and functions to discover and inspect packages.
class InstalledPackages:
"""
Interface to query installed R packages.
Provides access to information about packages
installed in the R environment.
"""
def __init__(self): ...
def __iter__(self): ...
def data(package) -> 'PackageData':
"""
Get datasets from R package.
Parameters:
- package: Package object or name
Returns:
PackageData object with access to package datasets
"""
def wherefrom(symbol: str, startswith: str = None):
"""
Find which package provides a symbol.
Parameters:
- symbol: R symbol/function name to search for
- startswith: Filter packages starting with this string
Returns:
Information about packages containing the symbol
"""
class PackageData:
"""
Datasets in an R package.
R packages can distribute datasets as part of their
functionality. This class provides access to those datasets.
"""
def fetch(self, name: str): ...Classes for handling R code parsing and execution.
class ParsedCode(rinterface.ExprSexpVector):
"""
Parsed R code expression vector.
Represents R code that has been parsed into an expression
vector suitable for evaluation.
"""
class SourceCode(str):
"""
R source code with parsing capabilities.
String subclass that provides methods to parse R source
code into executable expressions.
"""
def parse(self): ...Exceptions specific to package management operations.
class LibraryError(ImportError):
"""Base exception for library/package related errors."""
class PackageNotInstalledError(LibraryError):
"""Exception raised when attempting to import non-installed R package."""from rpy2.robjects.packages import importr, isinstalled
from rpy2.robjects import r
# Check if package is installed
if isinstalled('ggplot2'):
print("ggplot2 is available")
else:
print("ggplot2 is not installed")
# Import common R packages
try:
stats = importr('stats')
base = importr('base')
utils = importr('utils')
print("Base R packages imported successfully")
except PackageNotInstalledError as e:
print(f"Package import failed: {e}")
# Use R functions through package interface
data = [1, 2, 3, 4, 5]
mean_result = stats.mean(data)
print(f"Mean: {mean_result[0]}")
# Install packages via R (requires proper R configuration)
try:
r('install.packages("ggplot2", repos="https://cran.r-project.org")')
print("Package installation initiated")
except Exception as e:
print(f"Installation failed: {e}")
# Import newly installed packages
try:
ggplot2 = importr('ggplot2')
print("ggplot2 imported successfully")
except PackageNotInstalledError:
print("ggplot2 installation may have failed or requires restart")
# Handle package import with custom translation
# Map R's snake_case functions to Python camelCase
translations = {
'read_csv': 'readCsv',
'write_csv': 'writeCsv'
}
if isinstalled('readr'):
readr = importr('readr', robject_translations=translations)
# Now can use readr.readCsv instead of readr.read_csv
# Access package metadata
try:
from rpy2.robjects.packages import InstalledPackages
installed = InstalledPackages()
# Iterate through installed packages
package_count = 0
for pkg in installed:
package_count += 1
if package_count <= 5: # Show first 5 packages
print(f"Installed package: {pkg}")
print(f"Total packages checked: {package_count}")
except Exception as e:
print(f"Could not list packages: {e}")
# Suppress package loading messages
quiet_stats = importr('stats', suppress_messages=True)
# Import with custom symbol resolution
def r_to_python_name(r_name):
"""Convert R names to Python-friendly names."""
return r_name.replace('.', '_').replace('-', '_')
if isinstalled('somepackage'):
custom_package = importr('somepackage', symbol_r2python=r_to_python_name)
# Handle naming conflicts
package_with_conflicts = importr('package_name', on_conflict='resolve')
# Access package without signature translation for better performance
if isinstalled('stats'):
fast_stats = importr('stats', signature_translation=False)
# Get package datasets
if isinstalled('datasets'):
datasets = importr('datasets', data=True)
iris_data = data(datasets).fetch('iris')
print(f"Iris dataset shape: {iris_data.nrow} x {iris_data.ncol}")
# Find which package provides a function
from rpy2.robjects.packages import wherefrom
function_info = wherefrom('lm') # Linear model function
print(f"lm function provided by: {function_info}")# Bioconductor packages
try:
# First install BiocManager if needed
r('''
if (!require("BiocManager", quietly = TRUE))
install.packages("BiocManager")
BiocManager::install(c("Biobase", "limma"))
''')
# Import Bioconductor packages
if isinstalled('Biobase'):
biobase = importr('Biobase')
print("Biobase imported successfully")
except Exception as e:
print(f"Bioconductor setup failed: {e}")
# Check and install multiple packages
required_packages = ['dplyr', 'ggplot2', 'tidyr']
missing_packages = []
for pkg in required_packages:
if not isinstalled(pkg):
missing_packages.append(pkg)
if missing_packages:
# Install missing packages
pkg_list = ', '.join([f'"{pkg}"' for pkg in missing_packages])
r(f'install.packages(c({pkg_list}))')
# Verify installation
for pkg in missing_packages:
if isinstalled(pkg):
print(f"{pkg} installed successfully")
else:
print(f"{pkg} installation failed")
# Import all required packages
imported_packages = {}
for pkg in required_packages:
if isinstalled(pkg):
imported_packages[pkg] = importr(pkg)
print(f"Successfully imported {len(imported_packages)} packages")
# Package version information
if isinstalled('stats'):
stats_pkg = InstalledPackage('stats')
print(f"Stats package version: {stats_pkg.version}")
print(f"Stats package description: {stats_pkg.description}")# Always check if package is installed before importing
def safe_importr(package_name, **kwargs):
"""Safely import R package with error handling."""
if not isinstalled(package_name):
raise PackageNotInstalledError(f"Package '{package_name}' is not installed")
try:
return importr(package_name, **kwargs)
except Exception as e:
raise LibraryError(f"Failed to import '{package_name}': {e}")
# Use context managers for temporary package imports
from contextlib import contextmanager
@contextmanager
def temp_package(package_name, **import_args):
"""Temporarily import a package."""
if isinstalled(package_name):
pkg = importr(package_name, **import_args)
try:
yield pkg
finally:
# Package cleanup if needed
pass
else:
raise PackageNotInstalledError(f"Package '{package_name}' not available")
# Usage
with temp_package('ggplot2') as ggplot2:
# Use ggplot2 functions
plot = ggplot2.ggplot(data)
# Package reference goes out of scope after contextInstall with Tessl CLI
npx tessl i tessl/pypi-rpy2