Dias atrás a galera do RStudio lançou uma nova versão do {reticulate}
(pacote responsável pela interface do python dentro do R), que veio acompanhada de um post no blog deles (veja o post aqui). Foi através do post deles que descobri a existência do pacote {rminiconda}
! Esse pacote resolve problemas de compatibilidade de versões do python e é justamente isso que gostaria de registrar aqui nesse post.
Por que python?
A popularidade de python tem crescido nos últimos anos, puxado especialmente pelas bibliotecas de data science (digo data science de uma maneira geral, por exemplo, manipulação e análises de dados, entre outros). Veja aqui e aqui o crescimento do python nos últimos anos. Se você tem interesse nessa área, vale a pena aprender python. Vale lembrar que jornalistas também estão usando análise de dados para embasar suas apurações.
Uso o R diariamente, mas algumas soluções analíticas ou mesmo de visualização só estão disponíveis em python. Por que eu ficaria preso a uma linguagem se existe a solução em outra? Instalar e usar o python não é uma tarefa difícil (especialmente no Linux). Porém, usar as duas linguagens ao mesmo tempo sempre foi uma barreira pra mim. Existem soluções no Jupyter Notebook, mas eu gostaria de usar isso no RMarkdown. Ter as duas linguagens rodando no RMarkdown dentro do RStudio seria o melhor dos dois mundos.
Vamos ver como isso funciona.
Instalação das dependências
Você precisará instalar o python, o R e o RStudio para essa solução funcionar. A instalação das linguagens e do RStudio não é foco desse post. No entanto, deixarei aqui os links que te levarão para os downloads.
Baixe o R aqui: https://cran.r-project.org/
Baixe o RStudio aqui (baixe a versão free): https://rstudio.com/products/rstudio/download/
Baixe e instale o python usando o Anaconda (baixe a versão 3.7): https://www.anaconda.com/distribution/
Usando o python dentro do RStudio
Para usar o python dentro do R, temos duas opções. A primeira é usar o RMarkdown. Com ele, podemos mesclar códigos em R e em python. Podemos inclusive usar os objetos criados pelo python (um data frame, por exemplo) no R. A operação contrária também funciona. Para usar o python no RMkardown, crie um novo arquivo RMarkdown clicando em “File” na barra de status, depois clique em “R Markdown”.
A segunda opção para utilização do python é usando um script python. Porém, não será tão simples reutilizar os objetos criados por cada linguagem em uma mesma sessão do R. Para usar um script python no RStudio, clique em “File” na barra de status, depois clique “New file” e finalmente em “Python script”.
Neste post, vou utilizar o RMarkdown. Com ele, podemos inserir chunks para diversas linguagens. Ao abrir um novo arquivo RMarkdown você verá a seguinte opção:
São essas opções que permitem usar uma ou mais linguagens em um mesmo arquivo RMarkdown.
Instalação dos pacotes necessários no R
A rotina abaixo vai instalar os pacotes do R necessários para rodar o python no RMarkdown. O {reticulate}
é o pacote que vai facilitar o uso do python no RStudio e o {rminiconda}
é o pacote que vai isolar a versão do python que vamos utilizar aqui. O conflito entre diferentes versões do python instaladas em um mesmo sistema operacional é muito comum. O {rminiconda}
resolve esse problema. Os outros pacotes da lista abaixo darão suporte a algumas rotinas implementadas aqui.
Vale lembrar que, até a data desse post, o {rminiconda}
ainda não foi publicado no repositório oficial de pacotes do R (CRAN). Aqui, utilizaremos a última versão disponível no github.
if (!require("reticulate"))
install.packages("reticulate")
if (!require("tidyverse"))
install.packages("tidyverse")
if (!require("glue"))
install.packages("glue")
if (!require("remotes"))
install.packages("remotes")
if (!require("rminiconda"))
install_github("hafen/rminiconda")
Com os pacotes devidamente instalados, precisamos checar a versão do {reticulate}
, que deve ser no mínimo a 1.14:
packageVersion("reticulate")
## [1] '1.14'
A próxima etapa é instalar um novo ambiente com o {rminiconda}
e configurá-lo no {reticulate}
. Nosso novo ambiente vai se chamar testando_rminiconda
. Você pode escolher outro nome se preferir.
env_name <- "testando_rminiconda"
A rotina abaixo vai checar se o ambiente env_name
já existe. Caso não exista, ela vai instalar um novo ambiente.
check_setup_rminiconda <- function(env_name) {
python_for_r <- rminiconda::find_miniconda_python(env_name)
reticulate::use_python(python_for_r, required = TRUE)
message(glue("Ambiente `{env_name}` configurado no `reticulate`!"))
}
install_setup_rminiconda <- function(env_name) {
if (rminiconda::is_miniconda_installed(name = env_name)) {
message(glue("Ambiente `{env_name}` já existe!"))
check_setup_rminiconda(env_name)
} else {
message("Instalando novo ambiente: `{env_name}`!")
rminiconda::install_miniconda(name = env_name)
check_setup_rminiconda(env_name)
}
}
install_setup_rminiconda(env_name)
## Ambiente `testando_rminiconda` já existe!
## Ambiente `testando_rminiconda` configurado no `reticulate`!
Uma vez instalado, testamos se o ambiente está funcionando:
rminiconda::test_miniconda(env_name)
## [1] "hello world"
Se você viu um “hello world”, o ambiente está instalado e funcionando!
Instalação das bibliotecas do python pelo R
Agora, seguimos para uma instalação isolada das bibliotecas do python usando a função rminiconda_pip_install()
. Para instalar o pandas
, usaremos:
rminiconda_pip_install(pkg_name = "pandas", name = env_name)
Usaremos uma rotina para automatizar a instalação de várias bibliotecas. Primeiro, criamos uma função pra isso:
pip_install_pkg <- function(pkgs_py, update = FALSE) {
if (update == TRUE) {
pip_update_arg <- "-U"
} else {
pip_update_arg <- ""
}
pkgs_py %>%
purrr::map(
~rminiconda_pip_install(
pkg_name = .x,
name = env_name,
args = pip_update_arg
)
)
}
Listamos as bibliotecas de interesse:
pkgs_py <- c(
"pandas",
"numpy",
"matplotlib"
)
E usamos nossa função:
pip_install_pkg(pkgs_py)
Usando python no R
Agora, insira um chunk para python para utilizar as bibliotecas instaladas (a execução do código em python também pode ser feita com Ctrl+Enter):
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
Com as bibliotecas carregadas, podemos explorar alguns comandos. Vamos criar data frame com valores aleatórios com pandas
e fazer um gráfico com o matplotlib
.
df = pd.DataFrame(
np.random.randint(0, 100, size=(100, 4)
),
columns=list('ABCD')
)
Checando o data frame.
df.head()
## A B C D
## 0 48 88 13 13
## 1 80 38 1 80
## 2 94 64 74 55
## 3 0 76 2 55
## 4 58 74 91 79
Plotando um scatter plot.
fig = plt.figure()
plt.scatter(df['A'], df['B'])
plt.title('Scatter plot em python dentro do R')
plt.xlabel('Coluna A')
plt.ylabel('Coluna B')
plt.show()
Reutilizando objetos do python no R
Podemos reutilizar os objetos criados em python no R. Os objetos criados em python são armazenados na memória e podem ser recuperados usando o comando py$
em chunk para R. Esse comando vai listar os objetos do python armazenados na memória. Por exemplo, insira um chunk para R e recupere o data frame usando:
py$df
Vamos atribuir o resultado do comando anterior a um objeto no R.
r_df <- py$df
Checando o data frame no R.
head(r_df)
## A B C D
## 1 48 88 13 13
## 2 80 38 1 80
## 3 94 64 74 55
## 4 0 76 2 55
## 5 58 74 91 79
## 6 52 17 18 90
Plotando.
r_df %>%
ggplot(aes(x = A, y = B)) +
geom_point() +
labs(
title = "Scatter plot no R usando data frame do python",
x = "Coluna A",
y = "Coluna B"
)
Reutilizando objetos do R no python
Usar objeto do R no python também funciona. Vamos usar o dataset mtcars
para testar isso. Primeiro, carregamos o dataset.
data("mtcars")
Checando.
head(mtcars)
## mpg cyl disp hp drat wt qsec vs am gear carb
## Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
## Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
## Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
## Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
## Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
## Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
Para recuperarmos o objeto do R no python, usaremos a função a função r_to_py()
do {rminiconda}
.
r_to_py(mtcars)
Vamos atribuir o reultado do comando anterior a um objeto no R.
mtcars_py <- r_to_py(mtcars)
Agora esse objeto pode ser recuperado pelo python usando o comando r.
em um chunk para python. Esse comando vai listar os objetos do R que estão disponíveis para o python:
r.mtcars_py
Vamos atribuir o resultado do comando acima a um objeto em python.
mtcars_py = r.mtcars_py
Checando.
mtcars_py.head()
## mpg cyl disp hp drat ... qsec vs am gear carb
## Mazda RX4 21.0 6.0 160.0 110.0 3.90 ... 16.46 0.0 1.0 4.0 4.0
## Mazda RX4 Wag 21.0 6.0 160.0 110.0 3.90 ... 17.02 0.0 1.0 4.0 4.0
## Datsun 710 22.8 4.0 108.0 93.0 3.85 ... 18.61 1.0 1.0 4.0 1.0
## Hornet 4 Drive 21.4 6.0 258.0 110.0 3.08 ... 19.44 1.0 0.0 3.0 1.0
## Hornet Sportabout 18.7 8.0 360.0 175.0 3.15 ... 17.02 0.0 0.0 3.0 2.0
##
## [5 rows x 11 columns]
Plotando.
fig = plt.figure()
plt.scatter(mtcars_py['mpg'], mtcars_py['qsec'])
plt.title('Scatter plot do data frame do R em python')
plt.xlabel('mpg')
plt.ylabel('qsec')
plt.show()
É isso!