No meu último post sobre shiny, mostrei como é possível usar o pacote {golem}
como framework para desenvolvimento de shiny apps como pacotes. O processo de desenvolvimento se torna ligeiramente mais burocrático, mas os ganhos em consistência e reprodutibilidade são enormes.
Mas eu acho que faltou uma coisa no post. Eu não deixei clara qual é a grande vantagem de desenvolver um app usando o golem: o poder de rodar seu app com uma linha de código.
Nosso objetivo será chegar num código assim:
shiny::shinyApp(meuPacote:::app_ui(), meuPacote:::app_server)
Isso é tudo que você precisará subir em uma máquina na nuvem ou no shinyapps.io!
Para conseguir isso, no entanto, você precisará fazer duas coisas:
- Certifique-se de que seu app funciona com o pacote instalado numa sessão nova.
- (para o shinyapps.io) coloque seu app no github e instale o pacote de lá.
- Criar um arquivo
app.R
com o códigoshiny::shinyApp(meuPacote:::app_ui(), meuPacote:::app_server)
e subir para seu servidor ou para o shinyapps.io.
Certifique-se de que seu app funciona.
Uma boa forma de garantir que seu app funciona é fazendo-o passar no devtools::check()
. Se tudo der certo nessa etapa, a probabilidade de dar algum problema no passo (1) colocado acima é realmente baixa.
Recomendo fortemente a leitura do livro Zen do R para trilhar o caminho do desenvolvimento de pacotes sem dor nem sofrimento.
Trabalhando com bases exportadas dentro do pacote
Se o seu Shiny App utiliza bases de dados, sua base deve ser adicionada na pasta data/
de seu pacote. O problema é que, como as bases na pasta data/
são exportadas, elas não são diretamente acessíveis por funções internas do pacote. Para resolver esse problema, existem duas alternativas:
- Utilizar
::
sempre que for acessar sua base nas funções de seu Shiny App. Usualmente isso ocorrerá apenas algumas vezes, pois é uma boa prática criar umreactive()
que carrega e filtra os dados, e fazer todas as outras funcionalidades do app dependerem dessereactive()
. Por exemplo:
app_ui <- function() {
tagList(
plotOutput("grafico")
)
}
app_server <- function(input, output, session) {
# esse é o reactive que controla seus dados.
# se você tiver muitas bases no seu app, uma boa
# ideia é colocá-los numa lista neste reactive()
dados <- reactive({
meuPacote::cars
})
# a partir daqui, você não usa mais a base do pacote,
# mas sim o que vem do reactive()
output$grafico <- renderPlot({
plot(dados())
})
}
- Tratar seus dados como dados internos. Para isso, você deverá usar
usethis::use_data(dados, internal = TRUE)
. Nessa alternativa, seus dados ficarão num arquivo chamadosysdata.rda
. A vantagem nesse caso é que você não precisará usar o::
sempre que for acessar seus dados. A desvantagem é que todas suas bases ficarão em um arquivo só, o que pode causar confusões.
É isso. Happy coding ;)