Por que e como criar environments locais no R? - Análise Macro
Por que e como criar environments locais no R?
By Fernando da Silva 8 de outubro de 2021 No Comments
Joãozinho é um usuário ativo de R que trabalha simultaneamente em múltiplos projetos de trabalho/faculdade. A medida que os projetos avançam Joãozinho começou a encontrar algumas dificuldades: no projeto A ele precisa de algumas versões específicas de pacotes de R, enquanto que no projeto B ele precisa de alguns desses pacotes em versões mais recentes/diferentes por conta de atualizações de sintaxe, caso contrário o seu código para de funcionar. A solução gambiarra que Joãozinho encontrou foi instalar a versão específica dos pacotes que precisa toda vez que abre cada um dos projetos, para assim poder seguir desenvolvendo os códigos.
A solução de Joãozinho é adequada/eficiente? O que será que ele está fazendo de errado? Você está vivenciando algo parecido? Nesse tutorial iremos explorar o básico de criação de environments locais e independentes para cada projeto de R, permitindo que Joãozinho se livre dessas gambiarras e possíveis conflitos entre projetos.
Aviso 1: se você não sabe o que é ou nunca trabalhou com projetos de R (arquivos .Rproj), você deveria ler urgentemente esse texto.
Aviso 2: neste tutorial iremos utilizar o R 4.1.0 e o pacote renv v0.14.0.
O que são environments locais?
O termo "environment local" talvez não seja o mais acurado e descritivo possível, mas entenda como a biblioteca local de um projeto de R ou um gerenciamento de pacotes/dependências, separada da instalação global de pacotes de R que você tem no computador. Isso significa que quando você está trabalhando em um projeto de R usando um environment local, qualquer pacote que for instalado/removido não afetará os pacotes instalados globalmente em seu computador, pois essas alterações são independentes e feitas somente para o projeto de R em questão. Abre-se, então, a possibilidade de ter entre cada projeto versões diferentes de um mesmo pacote. Isso é bastante interessante, não?
Por que usar environments locais?
Situações em que os seus códigos de um projeto de R param de funcionar com o tempo são irritantes para qualquer um, ainda mais se considerarmos o custo de tempo gasto para fazer a manutenção do código. Dessa forma, qualquer organização ou usuário - como o Joãozinho - que use um gerenciamento de dependências adequado diminuirá significativamente o tempo gasto por desenvolvedores, cientistas e analistas de dados, etc. corrigindo códigos quebrados devido a alterações de versões de pacotes.
Em contraste com a comunidade de Python, que parece muito familiarizada com seu gerenciamento de dependências virtualenv ou pipenv, a comunidade de R não parece ter adotado amplamente essa prática. Talvez o viés mais estatístico da comunidade de R explique essa diferença. De qualquer forma, se você usa intensamente o R, você tem muito a ganhar em produtividade com a adoção do gerenciamento de pacotes!
Apesar da construção de um environment local não ser um procedimento nada trivial se "feito à mão", sua operacionalização na prática é extremamente simples, graças ao pacote renv. As principais vantagens de usar esse pacote, conforme destacado na documentação, são:
Isolamento: instalar, remover ou atualizar pacotes não fará com que seus outros projetos de R parem de funcionar, pois para cada projeto é criado um environment (biblioteca) local;
Portabilidade: estrutura facilitada para trabalhar com seus projetos de um computador para outro, ou até mesmo em sistemas operacionais diferentes;
Reprodutibilidade: graças ao registro exato de cada versão de pacote que o projeto depende, fica fácil abrir o projeto em outro ambiente e ter a mesma "fotografia" de pacotes utilizados e assim seguir com o trabalho/código normalmente.
A filosofia do pacote é de que o seu projeto de R deve continuar funcionando normalmente, com a vantagem agora de que o renv irá introduzir uma estrutura de gerenciamento de dependências, tornando o projeto mais robusto e reprodutível.
Agora que você já conhece o renv, vamos para a parte prática. Primeiro certifique-se de que tenha o pacote instalado:
# Versão CRAN
# Versão GitHub
remotes::install_github("rstudio/renv")
O fluxo de trabalho básico ao utilizar o renv em um projeto de R pode ser resumido em 2 funções bem simples:
Execute renv::init() para criar uma estrutura de biblioteca local para o projeto de R ativo. A função detecta os pacotes usados no projeto ativo e registra eles em um arquivo chamado renv.lock . Você pode executar essa função em projetos existentes ou em recém criados.
Trabalhe em seu projeto normalmente, instalando, removendo ou atualizando pacotes de R conforme necessidade. Se você executou o comando anterior em um projeto recém-criado, você precisará instalar pacote por pacote conforme utilizá-los.
Execute renv::snapshot() para salvar o estado atual do seu projeto. Isso fará com que os pacotes instalados/removidos durante a sessão sejam registrados no arquivo renv.lock . Confira as mensagens que aparecem no Console, o pacote proporciona uma experiência bastante "self-service".
E isso é praticamente tudo que você precisa saber de início para operacionalizar um environment local para seu projeto de R! Muito simples, não?
Uma vez que você seguiu esses passos você deve ter algo parecido com essa estrutura de arquivos no seu projeto de R:
Na pasta renv será criada a estrutura de biblioteca local para o seu projeto. O arquivo renv.lock mantém o último registro (renv::snapshot) de todos os pacotes, incluindo versões, utilizados no projeto. Por fim, o arquivo .Rprofile terá uma linha de comando de R para fazer com que seu projeto sempre inicialize o renv ao ser aberto.
Na aba Packages do RStudio também será possível notar visualmente os pacotes da biblioteca local do projeto:
Uma dica importante caso fique com dúvidas em algum momento do fluxo de trabalho usando o renv no projeto é a obtenção do status atual do gerenciamento de dependências com a função renv::status() que reporta a diferença entre os pacotes atualmente usados no projeto com o que está registrado no arquivo renv.lock .
Outra dica: quando você quiser reverter para um estado anterior registrado no renv.lock , devido a problemas trazidos por uma instalação de pacote ou algo do tipo, basta executar renv::restore() .
Por fim, recomendo dar uma olhada na documentação do pacote, para mais informações e detalhes das funcionalidades do renv . Tenho certeza de que uma vez que você começar a utilizá-lo e dar tempo suficiente para se acostumar com ele em seu fluxo de trabalho, jamais irá se arrepender ou criar projetos sem gerenciamento de dependências!