rpy2 embeds R inside a Python process
Interface to use R from Python
At a glance
- What is it?
- rpy2 is a Python interface to the R language through an embedded R, split into a C API binding package and an object layer package with optional numpy, pandas and IPython integrations. It suits a data science team that lives in Python but needs an R package, and it needs R itself installed and correctly discoverable.
- Who is it for?
- Adopt rpy2 when your Python code genuinely needs to call an R function that has no Python equivalent and you can accept embedding R in the same process. Do not adopt it for a simple data exchange, since a file or a database will do that with far less coupling, and do not expect it to work without R installed on the machine.
- Can I use it commercially?
- Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Embedded R, not a subprocess
rpy2 is an interface to use R from Python, and the key phrase in the package description is embedded R. That distinction sets the whole design. rpy2 does not shell out to Rscript and parse its output, and it does not speak a wire protocol to a separate R server. It loads the R shared library into the Python process and calls into it, so R objects, R functions and R's own error handling are available in the same address space. The practical consequences are mostly favourable. A call into R is a function call, so data structures can be passed across without a serialisation step, and an R package can be used without reimplementing it. The practical consequence that bites is process level. There is one R runtime per process, its memory is your memory, and the R initialisation is not free. The project is licensed GPL-2.0-or-later, and the README makes the point plainly, saying that this is the very same license R itself is released under, which is a deliberate choice rather than an accident given how the library links.
Two packages, and the split is deliberate
rpy2 is a namespace package with its constituting parts in different sub-packages, and the tree shows the split. rpy2-rinterface contains the binding to R's C API, and rpy2-robjects is the higher layer built on it. The top level package depends on both, with rpy2-rinterface at 3.6.7 or newer and rpy2-robjects at 3.6.6 or newer, and the top level version in the manifest is 3.6.9. The build system requires setuptools 61 or newer, wheel, and cffi at 1.15.0 or newer, with packaging added on Windows. The reason the C binding is separated from the object layer is that the binding has its own build cost. Building from source requires a compilation toolchain and developer tools, and the README is honest that you will have to figure out how to get those installed on your system. The mitigation is that the CI pipeline builds binary wheels for Linux, macOS and Windows, and the README says that watching how the CI sets things up is pretty much all the documentation the package maintainers provide on the matter. In practice that means pip install gets you a wheel and the source build is the exception.
Extras for numpy, pandas, IPython and the documentation
The optional dependencies are where the practical value sits for a data science workflow, and they are declared as named groups in the manifest. The numpy group pulls numpy support into both the interface and the object packages, and the pandas group does the same for pandas, with the interface listed alone and the objects layer carrying the pandas extra. There is a types group with mypy and types-tzlocal for type checking, a doc group with pygraphviz and sphinx, a test group that depends on the test extras of both sub-packages, and an all group that asks for everything. The README names the practical ones, saying that installing all optional dependencies covers numpy, pandas and ipython, and shows the two commands for the test extra and the all extra. The optional dependencies are described as providing specific functionalities not otherwise required to use the rest of rpy2, which is the right framing, since the base install is deliberately small.
The shared library problem is the one that eats an afternoon
There is a section of the README devoted to issues loading shared C libraries, and it is worth reading before you install anything. Whenever R is not installed in a system location, the system might not know where to find the R shared library. The symptom is specific and confusing: if R is on the PATH, so that entering R on the command line successfully starts an R terminal, rpy2 still does not work because of missing C libraries. The fix is to export the library path before starting Python:
export LD_LIBRARY_PATH="$(python -m rpy2.situation LD_LIBRARY_PATH)":${LD_LIBRARY_PATH}The command asks the rpy2 package itself where the R library lives and prepends that to the path, which is more robust than hardcoding a path because the R installation may be in a conda prefix, a custom location or a versioned directory. If your R is somewhere unusual, this line belongs in your shell profile or in whatever launches the Python process. It is the single most common setup failure for this package, and it produces an error that points at the loader rather than at rpy2.
Installing and testing from the source tree
A released version installs from a package repository, PyPI by default, and the README gives both pip and uv forms. For a developer working in the source tree, the install is the three sub-package paths, because the namespace package is assembled from them:
pip install ./rpy2-rinterface/ ./rpy2-robjects/ .The optional dependencies can be requested per sub-package with the extras syntax on the first two and the third, so a developer with everything enabled installs the all extras for the interface and the objects packages and for the top level. The test setup is pytest with the pytest-cov plugin for coverage, and the README gives the command to test the package from the source tree, which takes the two sub-package directories. A longer form follows for coverage with several targets named, covering the rinterface library, the rinterface package, the ipython module and the robject package, across the same two directories. The pytest configuration in the manifest sets a minimum version of 6.0 and points the test paths at rpy2/tests.
Editorial conclusion
Adopt rpy2 when your Python code genuinely needs to call an R function that has no Python equivalent and you can accept embedding R in the same process. Do not adopt it for a simple data exchange, since a file or a database will do that with far less coupling, and do not expect it to work without R installed on the machine. Verify first that R is on your PATH, that the shared R library can be found by your loader, and that the R installation is a version your rpy2 release supports, since the process crashes rather than degrading when the library cannot be loaded.
Frequently asked questions
How do I install rpy2 and its optional dependencies?
Install a released version with pip install rpy2, or the equivalent uv pip install. The extras are named groups, so pip install 'rpy2[test]' adds what the unit tests need, and pip install 'rpy2[all]' adds every optional dependency including numpy, pandas and ipython.
What do the rpy2-rinterface and rpy2-robjects packages do?
rpy2-rinterface contains the binding to R's C API, and rpy2-robjects is the higher object layer built on it. rpy2 is a namespace package assembled from those sub-packages, and the top level package depends on rpy2-rinterface 3.6.7 or newer and rpy2-robjects 3.6.6 or newer, with the top level version at 3.6.9.
Why does rpy2 fail even though R works in my terminal?
Because R is not installed in a system location, the system might not know where to find the R shared library even though the R command itself works. The README's fix is to export LD_LIBRARY_PATH before starting Python using the value that python -m rpy2.situation LD_LIBRARY_PATH reports.
How do I run the rpy2 tests from the source tree?
rpy2 uses pytest with the pytest-cov plugin for coverage. Run pytest with the rpy2-rinterface/ and rpy2-robjects/ directories to test the package, and add the cov flags for the rinterface library, the rinterface package, the ipython module and the robject package when you want a coverage report.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/rpy2-rpy2)Was this useful?