-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Estudar a viabilidade de executar códigos R em Python #147
Comments
Existe um pacote chamado rpy2 que se propõe a executar funções de pacotes R dentro de um programa python.
No windows, somente consegui instalá-lo em um ambiente virtual no Python 3.10 e a versão do rpy2 sendo 3.5.12 (em versões mais recentes ocorreu erro de instalação): py -3.10 -m venv venv
source venv/Scripts/activate
pip install rpy2==3.5.12 e o seguinte snipet foi executado utilizando o rpy2, definindo uma função R e recebendo o resultado dela no Python: import rpy2.robjects as ro
from rpy2.robjects.packages import importr
# Load the R base package
base = importr('base')
# Load a specific R package (e.g., ggplot2)
ggplot2 = importr('ggplot2')
# Define an R function and use it
ro.r('''
my_function <- function(x) {
return(x + 1)
}
''')
# Call the R function from Python
r_my_function = ro.globalenv['my_function']
result = r_my_function(5)
print(result[0]) # Output will be 6
Também foi possível acessar pelo Python um dataframe criado no R (vetores e dataframes são objetos geralmente retornados pelo pacote relatórios): import rpy2.robjects as ro
import pandas as pd
from rpy2.robjects import pandas2ri
# Activate the pandas2ri conversion
pandas2ri.activate()
# R code to create a data.frame
ro.r('''
my_dataframe <- data.frame(
column1 = c(1, 2, 3, 4),
column2 = c('A', 'B', 'C', 'D'),
stringsAsFactors = FALSE
)
''')
# Access the R data.frame
r_dataframe = ro.globalenv['my_dataframe']
# Display the Python DataFrame
print(r_dataframe)
Por fim, foi possível criar um dataframe no Python, passa-lo para o R e recuperá-lo. Em seguida é adicionada uma coluna a esse dataframe dentro do R e repassado esse dataframe modificado para o Python (convertendo-o também em um dataframe do pandas): import pandas as pd
import rpy2.robjects as ro
from rpy2.robjects import pandas2ri
# Activate the conversion between pandas and R data frames
pandas2ri.activate()
# Step 1: Create a pandas DataFrame in Python
df_python = pd.DataFrame({
'column1': [1, 2, 3, 4],
'column2': ['A', 'B', 'C', 'D']
})
# Convert the pandas DataFrame to an R data.frame
r_dataframe = pandas2ri.py2rpy(df_python)
#step 2: Pass the dataframe to rpy2
ro.globalenv['r_dataframe'] = r_dataframe
# Step 3: Define and apply an R function
# (for example, here we're just returning the summary of the dataframe)
ro.r('''
# R code that manipulates the dataframe
result <- summary(r_dataframe)
''')
# Retrieve the result from R (could be a modified dataframe, list, or other object)
r_summary = ro.r('result')
# Prints the summary received from rpy2
print("-- Returned R dataframe summary --")
print(r_summary)
# Recover to Python the dataframe sent to R (note the type in python is <class 'rpy2.robjects.vectors.DataFrame'>)
r_dataframe = ro.r('r_dataframe')
print("\n-- R dataframe --")
print(r_dataframe)
# Adds a new line to the dataframe inside R
ro.r('''
new_row <- data.frame(column1 = 5, column2 = "E")
df_r <- rbind(r_dataframe, new_row)
''')
# receives dataframe with a new line and convert it back to pandas
pandas_dataframe = pandas2ri.rpy2py_dataframe(ro.globalenv['df_r'])
print("\n-- Pandas dataframe --")
print(pandas_dataframe)
|
@labanca, bastante interessante. Acredito que utilizar a versão Você chegou a montar/pensar em algum reprex para a chamada do pacote relatórios? Por falar nisso, ele fica em nossa organização (não achei nada em uma pesquisa rápida)? Poderia incluir o link aqui para mim? |
Não sei se entendi a pergunta, seria montar um reprex com esses exemplos? Acho que se você estiver perguntando sobre criar um exemplo do pacote relatórios sendo usado pelo
Os pacotes ficam no bitbucket na conta da DCGF: https://bitbucket.org/dcgf/relatorios/src/master/ |
@labanca, achei este issue no repo |
Discutimos isso na época, mas depois não seguimos com a ideia. Não recordo os motivos ao certo, mas creio que havia demandas mais urgentes e essa abordagem era complexa. |
Outro update sobre o estudo. É possível atribuir a um objeto Python um pacote, função ou código R e utilizá-lo no ambiente Python. Com isso eu consegui instanciar o pacote relatórios no Python e aplicar uma de suas funções na base acoes_planejamento e receber o resultado dessa função do pacote relatórios no Python: import rpy2.robjects as ro
from rpy2.robjects import pandas2ri
from rpy2.robjects.packages import importr
import unidecode
def clean_column_names(column_name):
"""
Reproduce the LOA project data cleansing on the dataframe to be able to use relatorios functions
"""
# Replace white spaces with dots
column_name = column_name.replace(" ", ".")
# Convert to unaccented equivalents
column_name = unidecode.unidecode(column_name)
# Convert to lower case
column_name = column_name.lower()
return column_name
# Activate the automatic conversion between R data frames and pandas DataFrames
pandas2ri.activate()
base = importr('base')
utils = importr('utils')
readr = importr('readr')
# You can convert a R package to a python object and use it in the python env
relatorios = importr('relatorios')
# Read the pipe-separated text file
acoes_planejamento = readr.read_delim("data/acoes_planejamento.txt", delim="|")
# Convert to pandas DataFrame
acoes_planejamento_df = pandas2ri.rpy2py(acoes_planejamento)
cleaned_column_names = [clean_column_names(name) for name in acoes_planejamento_df.columns]
acoes_planejamento_df.columns = cleaned_column_names
# LOA project names conventions (clunky)
nomes_esperados = [
"codigo.do.programa", "nome.do.programa", "codigo.da.unidade.orcamentaria.responsavel.pela.acao",
"codigo.da.funcao", "funcao", "codigo.da.subfuncao", "subfuncao",
"codigo.do.tipo.de.acao", "tipo.de.acao", "codigo.da.acao", "titulo.da.acao",
"codigo.do.identificador.de.acao.governamental..iag.", "exclusao.logica.da.acao",
"finalidade.da.acao", "codigo.do.produto", "produto", "unidade.de.medida.do.produto"
]
novos_nomes = [
"cod_prog", "nome_prog", "UO_COD",
"cod_funcao", "nome_funcao", "cod_subfuncao", "nome_subfuncao",
"cod_tipo_acao", "tipo_acao", "cod_acao", "titulo_acao",
"cod_iag", "exc_acao", "final_acao", "prod_acao",
"Produto", "unid_med_prod"
]
# Create a mapping from expected names to new names
name_mapping = dict(zip(nomes_esperados, novos_nomes))
# Rename the columns using the mapping, only if they exist in the DataFrame
acoes_planejamento_df.rename(columns=name_mapping, inplace=True)
# relatorios package need a column named ANO
acoes_planejamento_df['ANO'] = 2024
# Convert back to R DataFrame to apply the relatios function
acoes_planejamento_r = pandas2ri.py2rpy(acoes_planejamento_df)
# Assign the dataframe to R's global environment
ro.globalenv['acoes_planejamento'] = acoes_planejamento_r
# Call the function from the R package relatorios
result = relatorios.is_outros_poderes(ro.globalenv['acoes_planejamento'])
# Print the result
print(result) O resultado é um vetor booleano, o que é o retorno das funções do pacote
Há uma série de procedimentos que foram feitos para o exemplo que não necessariamente precisariam ser feitos. Como a base de dados ser lida utilizando o pacote |
@labanca, estou entendendo que a resposta para este Issue é SIM, conseguimos executar códigos R em Python. O que acha de fecharmos este Issue e já abrirmos um no dpm com a chamada para ação de criar esta funcionalidade lá? Como já estão definidas várias atividades para o mês de novembro, isso poderá entrar como prioridade para dezembro. O que acha? |
@gabrielbdornas estou bem empolgado com os resultados! Porém, acho que ainda temos de estudar um pouco mais. Tudo indica que é possível, mas um teste prático em alguma aplicação nossa seria mais seguro. E no caso, quais seriam as funcionalidades em R que viriam para o DPM? Hoje o DPM que é cuido somente possui código Python. |
@labanca, concordo em fazer o teste em alguma aplicação. Alguma sugestão de qual? Quanto às funcionalidades R que viriam para o |
See #148.
The text was updated successfully, but these errors were encountered: