Search code examples
pythonrpy2

Access a single R instance from multiple modules in package using rpy2


How can one ensure only one R instance is run and accessible from modules in a package using rpy2?

For example, imagine the top level of a package foobar having modules foo.py and bar.py, as well as a subpackage "tests" with test module test_foo.py:

.
├── tests
│   ├── __init__.py
│   ├── test_foo.py
├── foo.py
├── bar.py
├── __init__.py

Can one place rpy2 imports in, say, the top level init.py, and then have all the other modules import robjs. For example, the top level init.py can be:

from rpy2.robjects.packages import importr
import rpy2.robjects as robjs
import rpy2.robjects.conversion as cv
from import rpy2.robjects import pandas2ri

and then in the other modules:

import foobar

# Do stuff with foobar.robjs, foobar.cv, foobar.pandas2ri

Or is there a better arrangement to have modules share the same R instance?


Solution

  • Packages/modules are singletons in Python (there is only one "copy" of each module across all imports within the same program).

    You can import rpy2.robjects as robjs as many times and across as many modules as you like, it will the very same R "instance" within a process.

    To verify this you can add the following code snippet to all the modules you wrote for a program:

    import rpy2.robjects as ro
    rvar_name = 'import_%s' % __name__
    ro.globalenv[rvar_name] = True
    print('---')
    print(__name__)
    print(tuple(ro.globalenv.keys()))
    print('---')