Using Python inside of R with reticulate¶
A previous blog post covered
Using R inside of Conda, but what about
if you want to use Python packages inside an existing
R or
RStudio via OnDemand session?
This is where the
reticulate
R Interface to Python
comes in.
Remove previous reticulate
virtual environments
You may have previously been using ${HOME}/.virtualenvs
for storing Python
virtualenvs you have been using in R via reticulate
. To avoid issues, you
should remove these before following the instructions below.
Do not load any additional Python modules
reticulate
is now able to manage its own versions of Python, so there is
no need to load any additional Python modules to use it. Also, the use of
Conda via Miniforge
is not supported as Conda conflicts with the
Spack Environment
that is always loaded alongside R and RStudio. Should you wish to use R and
Conda together, please follow the instructions in
Using R inside of Conda.
Defining your required Python packages¶
reticulate
now uses uv
Versions 1.41 and newer of reticulate
now use
uv
for package and environment management.
Make sure you have an up to date version of reticulate
installed in your
personal R library before following the instructions below.
To define the Python packages you wish to use in your R session, first load
reticulate
:
library(reticulate)
Let's use numpy
as an example. reticulate
uses the
py_require()
command for Python package management, so let's use it for numpy
:
py_require("numpy")
Nothing will happen yet, but if we then move on to actually using numpy
in our
R shell:
> np <- import("numpy", convert = TRUE)
> np1 <- np$array(c(1:4))
> np1
[1] 1 2 3 4
To avoid the automatic translation of variables into R objects, you will need to
set your convert parameter to FALSE
:
> rm(np, np1)
> np <- import("numpy", convert = FALSE)
> np1 <- np$array(c(1:4))
> np1
array([1, 2, 3, 4])
If you are curious about what is happening in the background to achieve this,
you can use the py_discover_config()
command:
> py_discover_config()
python: /data/home/abc123/.cache/R/reticulate/uv/cache/archive-v0/Eb1EH3UVdTZsTkSboKndp/bin/python
libpython: /data/home/abc123/.local/share/uv/python/cpython-3.11.11-linux-x86_64-gnu/lib/libpython3.11.so
pythonhome: /data/home/abc123/.cache/R/reticulate/uv/cache/archive-v0/Eb1EH3UVdTZsTkSboKndp:/data/home/abc123/.cache/R/reticulate/uv/cache/archive-v0/Eb1EH3UVdTZsTkSboKndp
virtualenv: /data/home/abc123/.cache/R/reticulate/uv/cache/archive-v0/Eb1EH3UVdTZsTkSboKndp/bin/activate_this.py
version: 3.11.11 (main, Mar 17 2025, 21:02:09) [Clang 20.1.0 ]
numpy: /data/home/abc123/.cache/R/reticulate/uv/cache/archive-v0/Eb1EH3UVdTZsTkSboKndp/lib/python3.11/site-packages/numpy
numpy_version: 2.2.4
NOTE: Python version was forced by VIRTUAL_ENV
So, we can see that reticulate
has used uv
to spawn an ephemeral Python
virtual environment and has installed numpy
2.2.4 (the latest version at the
time of writing) into it.
Defining Python package versions¶
Numpy v2 introduced a large number of changes and not all workflows have adapted to these requirements. You may find that an error occurs similar to the below:
A module that was compiled using NumPy 1.x cannot be run in
NumPy 2.2.4 as it may crash. To support both 1.x and 2.x
versions of NumPy, modules must be compiled with NumPy 2.0.
Some module may need to rebuild instead e.g. with 'pybind11>=2.12'.
If you are a user of the module, the easiest solution will be to
downgrade to 'numpy<2' or try to upgrade the affected module.
We expect that some modules will need time to support NumPy 2.
In these cases, you can specify a version of numpy
via the py_require()
command:
py_require("numpy<2")
Note, you cannot run this as part of the existing session:
> py_require("numpy<2")
Error in py_require("numpy<2") :
After Python has initialized, only `action = 'add'` with new packages is supported.
This is because we already defined a version of Python and activated the
reticulate
interface to Python, so restart a new session before running the
new command:
> library(reticulate)
> py_require("numpy<2")
> np <- import("numpy", convert = FALSE)
Installed 1 package in 1.84s
Notice there that uv
has pulled in our requested version of numpy
.
Continuing:
> np1 <- np$array(c(1:4))
> np1
array([1, 2, 3, 4])
Let's check py_discover_config()
again:
> py_discover_config()
python: /data/home/abc123/.cache/R/reticulate/uv/cache/archive-v0/rxI39p9Uc4FbC9apPayGE/bin/python
libpython: /data/home/abc123/.local/share/uv/python/cpython-3.11.11-linux-x86_64-gnu/lib/libpython3.11.so
pythonhome: /data/home/abc123/.cache/R/reticulate/uv/cache/archive-v0/rxI39p9Uc4FbC9apPayGE:/data/home/abc123/.cache/R/reticulate/uv/cache/archive-v0/rxI39p9Uc4FbC9apPayGE
virtualenv: /data/home/abc123/.cache/R/reticulate/uv/cache/archive-v0/rxI39p9Uc4FbC9apPayGE/bin/activate_this.py
version: 3.11.11 (main, Mar 17 2025, 21:02:09) [Clang 20.1.0 ]
numpy: /data/home/abc123/.cache/R/reticulate/uv/cache/archive-v0/rxI39p9Uc4FbC9apPayGE/lib/python3.11/site-packages/numpy
numpy_version: 1.26.4
NOTE: Python version was forced by VIRTUAL_ENV
So, now we are using Numpy 1.26.4 (the last v1 release).
Using an alternative Python version¶
The above examples automatically used Python 3.11.11, but what if you want to
use, say, a newer version of Python like 3.12? In this case, you can define a
specific Python version using py_require(python_version = "<version>")
. So, in
a new R session:
> library(reticulate)
> py_require(python_version = "3.12")
Then, if we run our Numpy example again:
> library(reticulate)
> py_require("numpy")
> np <- import("numpy", convert = FALSE)
Installed 1 package in 199ms
Notice there that uv
has pulled in our requested version of Python, created a
new virtual environment, and installed numpy
into it.
Continuing:
> np1 <- np$array(c(1:4))
> np1
array([1, 2, 3, 4])
Let's check py_discover_config()
again:
> py_discover_config()
python: /data/home/abc123/.cache/R/reticulate/uv/cache/archive-v0/lMcGJfxMfO84OpH6yvDMy/bin/python
libpython: /data/home/abc123/.local/share/uv/python/cpython-3.12.9-linux-x86_64-gnu/lib/libpython3.12.so
pythonhome: /data/home/abc123/.cache/R/reticulate/uv/cache/archive-v0/lMcGJfxMfO84OpH6yvDMy:/data/home/abc123/.cache/R/reticulate/uv/cache/archive-v0/lMcGJfxMfO84OpH6yvDMy
virtualenv: /data/home/abc123/.cache/R/reticulate/uv/cache/archive-v0/lMcGJfxMfO84OpH6yvDMy/bin/activate_this.py
version: 3.12.9 (main, Mar 17 2025, 21:01:58) [Clang 20.1.0 ]
numpy: /data/home/abc123/.cache/R/reticulate/uv/cache/archive-v0/lMcGJfxMfO84OpH6yvDMy/lib/python3.12/site-packages/numpy
numpy_version: 2.2.4
NOTE: Python version was forced by VIRTUAL_ENV
So, Python 3.12.9 and Numpy 2.2.4.
Cache¶
reticulate
caches ephemeral environments in the directory returned by:
> tools::R_user_dir("reticulate", "cache")
[1] "/data/home/abc123/.cache/R/reticulate"
To clear the cache, delete the directory:
unlink(tools::R_user_dir("reticulate", "cache"), recursive = TRUE)
Conclusion¶
This blog post covers the basics of reticulate
, but for more detailed
documentation, please visit the
official reticulate
website.
As usual, you can ask a question on our Slack channel (QMUL users only), or by sending an email to its-research-support@qmul.ac.uk which is handled directly by staff with relevant expertise.