Tutorial de reticulate: cómo usar Python en R

Share on linkedin
Share on twitter
Share on email

Python y R son los dos principales lenguajes de programación en tema de datos. Los dos son geniales y polivalentes y, aunque seguramente tengamos uno preferido, para ciertas cosas siempre hay uno que es mejor. Ya explicamos cómo usar R en Python. Ahora toca aprender a usar Python en R. ¿Te imaginas poder combinar ambos lenguajes en tus ficheros RMarkdown o App Shiny? ¿Te suena bien? ¡Pues vamos a ello!

Reticulate: nunca combinar lenguajes fue tan fácil

Si en Python usamos rpy2 para usar R, en R tenemos la librería reticualte para usar Python. Por suerte reticulate es mucho más fácil de instalar y usar que rpy2. Así que vamos con ello!

install.packages("reticulate")
library(reticulate)

Seleccionar la versión de Python

Lo primero que tenemos que hacer es elegir la versión de Python que queremos usar. Hay tres formas de seleccionar la versión:

  1. Función use_python: indicas la ruta donde reside la carpeta Python. Fácil y sencillo. Si esta es tu opción, quizás te sea de interés usar la función file.choose para tener el path directamente.

  2. Función virtualenv_root: te permite especificar la ruta de un entorno virtual de Python. Los entornos virtuales funcionan como instalaciones de Python independientes, con sus paquetes y sus rutas específicas.

  3. Funciones use_condaenv o use_miniconda te permiten usar los entornos de Anaconda. Si quieres conocer qué entornos tienes, puedes usar lo siguiente: conda_list()[[1]]. Si no sabes dónde están, aquí te explica cómo encontrarlos.

  4. En mi caso, usaré la función use_python. Seguramente este también sea tu caso.

    use_python("C:/Users/Ander/Anaconda3/envs/r-reticulate/python.exe")

Cómo usar Python en RMarkdown

Una vez has fijado el entorno de Python, usarlo en RMarkdown es muy sencillo. Simplemente tienes que indicar en el chunk que use Python en vez de R. Para ello, en vez de abrir el chunk con {r}, usa {python}.
Ejemplo de un chunk en Python:

a = "Hola " + "Mundo"
print(a)
## Hola Mundo

Como ves, al cargar reticulate, simplemente con cambiar el lenguaje a usar ya podemos incluir código en Python. Además, las configuraciones de RMarkdown como echo,message, etc. siguen funcionando igual igual.

Sin embargo, esto tiene una pega y es que las variables generadas de esta forma no se guardan en el environment de R, sino que están en Python. Vamos, que si yo ahora compruebo si la variable existe en R, me dirá que no:

exists("a")
## [1] FALSE

¿Cómo podemos solucionar esto? Pasando las variables de un entorno a otro. Lo vemos.

Cambiando las variables de entorno

A la hora de llamar las variables de un entorno desde otro, tenemos dos casos: llamar una variable Python desde R o llamar a una variable de R en Python.

En cualquiera de los dos casos, lo que reticualte hace es “convertir” ese tipo de dato del lenguaje dado en otro tipo de dato. Así pues, un un vector de R con varios elementos se convertirá en una lista de Python, una lista de R en una Tupla, un dataframe de R en uno de Pandas, etc. En al siguiente imagen vemos las conversiones que hace el paquete:

Tabla de las conversiones de objetos que realizar el paquete reticulate al convertir código Python en R

Sin embargo, esta conversión tiene sus limitaciones, ya que las clases de objetos que no están en la lista (como un shapefile) no pueden ser convertidos, al menos de momento.

En cualquier caso, el ejemplo anterior (usar la variable a de Python en R) caería en el primer caso, así que, si te parece, empezamos por ese:

Llamar variables de Python desde R

Para llamar a variables de Python desde R únicamente tendremos que acceder a la variable de Python desde un código de R. Todas las variables creadas en Python están disponibles en el objeto py de R, por lo que simplemente tendremos que acceder al mismo:

py$a
## [1] "Hola Mundo"

Llamar variables de R desde Python

Para llamar a variables de R desde Python tenemos que acceder a los elementos del objeto r en Python. Un ejemplo se muestra a continuación:

b = "Buen dia!"
r.b
## 'Buen dia!'

Como ves, la forma de acceder variables entre ambos lenguajes es mucho más sencilla que en el caso de Python y rpy2.

Visto el uso de código de Python en RMarkdown, pero… ¿y si quiero usar ambos lenguajes simultáneamente en un mismo script de R? ¡Veámos!

Usar R y Python en un mismo script

Instalación y carga de librerías

Si usas tu entorno normal de Python, podrás acceder a las librerías que tengas ya instaladas ahí. Si quieres instalar nuevas, puedes hacerlo como de costumbre, usando el método pip y conda.

Si por el contrario trabajas en Anaconda o un entorno virtual, puedes instalar paquetes desde el propio código de R. Para instalar paquetes en los entornos Anaconda, usa la función conda_install, mientras que, en un entorno virtual, usa la función py_install.

En mi caso, instalo y cargo pandas en el entorno de reticulate.

py_install("pandas")

Usando código Python en R

Para usar Python y R indistintamente es bastante sencillo: debes declarar las variables de Python como si de variables R se tratara. Por defecto, reticulate convertirá los resultados de las operaciones en objetos de R, a menos que se indique lo contrario al importar una función.

np <- import("numpy", convert = TRUE)
np1 <- np$array(c(1:4))
np1
## [1] 1 2 3 4

Para no convertir los elementos automáticamente a R, debemos fijar el parámetro convert de la función import en FALSE

rm(np, np1)

np <- import("numpy", convert = FALSE)
np1 <- np$array(c(1:4))
np1
## [1 2 3 4]

Ejecutando un pedazo de código en Python

Seguramente te encuentres con la situación de que quieras correr un pedazo de código en Python. Tener que adaptarlo a esta nueva forma de declarar y acceder variables es un poco aburrido, ¿no podrían ejecutarse una serie de líneas directamente?

Pues sí, se puede, gracias a la función py_run_string. Esta función ejecuta el código en Python y mantendrá sus resultados en la sesión de Python, a menos que lo asignemos a una variable. Podrás acceder a esos mismos objetos desde R, como te he explicado más arriba. Veámos un ejemplo:

py_run_string("import numpy as np")
py_run_string("np2 = np.array(range(4))")

La principal pega de py_run_string es que debes ejecutar el código línea de línea, lo cual puede que no sea muy útil. Si, por el contrario, necesitas ejecutar muchas líneas, puede que la función py_run_file te sea más útil.

Esta función te permite ejecutar archivos de Python, por lo que una buena idea sería guardar tus funciones en ficheros separados e incluirlos en la sesión de R leyendo los archivos.

Reticulate: la unión hace la fuerza

Tanto R como Python son dos lenguajes muy potentes. Sin embargo, como habrás podido ver el paquete reticulate ofrece muchísimas opciones para poder combinar ambos lenguajes a un nivel bastante interesante. Con esto podrás combinar lo mejor de ambos mundos para poder crear impacto de una forma mucho más sencilla.

¿Te imaginas una app que se aproveche del potencial del Deep Learning de Python con la capacidad de interactividad de una App Shiny? ¿Y qué me dices usar paquetes especializados que existen en un lenguaje pero no en el otro? Porque al fin y al cabo, la unión hace la fuerza.