Prezadxs, olá!
Estou com umas dúvidas em shiny e resolvi passar todas de uma vez em um post pra ficar mais simples de obter alguma resposta.
O contexto é uma base que recebe o ano como um filtro pra gerar um gráfico a partir de uma base filtrada. Usei a base padrão da CursoR (imdb) pra poder montar esse exemplo.
O projeto consta no seguinte link do gitthub:
maykongpedro/duvidas-shiny-apps (github.com)
Minhas dúvidas são as seguintes:
-
Por que preciso declarar meu objeto de escolhas dentro do módulo? Se eu crio ele no script app.R e tento puxar ele no módulo, o shiny não encontra. O mesmo vale pra base, tive que colocar ela como um argumento da função server do módulo.
-
Como uso um selectInput/sliderInput colocado dentro do sideBar de um shinyDashboard nos módulos? Ou seja, no meu exemplo quero filtrar o ano na base, usar esse input dentro do módulo. Não consegui fazer essa referência.
-
Quando faço filtros na base para gerar gráficos ou tabelas, qual a melhor prática? Filtrar direto no
renderPlot
ou criar uma base_filtrada comreactive
? Vi que funciona das duas maneiras porém não consegui entender perfeitamente o conceito de usar oreactive
.
Os scripts seguem abaixo:
APP:
library(shiny)
library(shinydashboard)
#>
#> Attaching package: 'shinydashboard'
#> The following object is masked from 'package:graphics':
#>
#> box
# Carregar base -----------------------------------------------------------
imdb <- basesCursoR::pegar_base("imdb")
# 1. Por que o objeto de escolhas gerado aqui não é encontrado pelo módulo?
# gerar escolhas
# escolhas_ano <- seq(from = 2000, to = 2010, by = 1)
# ui ----------------------------------------------------------------------
ui <- dashboardPage(
# sempre nessa ordem: header -> siderbar -> body
dashboardHeader(title = "Dúvida"),
dashboardSidebar(
sidebarMenu(
menuItem(text = "Página 1", tabName = "pag1")
)
# 2. Como usar esse input aqui e ser reativo no módulo?
# sliderInput(
# inputId = "ano",
# label = "Selecione um ano",
# min = min(escolhas_ano),
# max = max(escolhas_ano),
# value = max(escolhas_ano),
# sep = ""
# )
),
dashboardBody(
tabItems(
tabItem(
tabName = "pag1",
conteudo_ui("grafico")
)
)
)
)
# server ------------------------------------------------------------------
server <- function(input, output, session) {
conteudo_server("grafico", imdb)
}
shinyApp(ui, server)
Created on 2021-12-01 by the reprex package (v2.0.1)
Módulo
# UI ----------------------------------------------------------------------
conteudo_ui <- function(id){
# 1. Por que preciso declarar as escolhas aqui e não somente no app?
escolhas_ano <- seq(from = 2000, to = 2010, by = 1)
ns <-NS(id)
tagList(
h2("Gráfico teste"),
fluidRow(
column(
width = 3,
# 2. Como uso esse input direto na sidebar?
# colocando um input
sliderInput(
inputId = ns("ano"),
label = "Selecione um ano",
min = min(escolhas_ano),
max = max(escolhas_ano),
value = max(escolhas_ano),
sep = ""
)
)
),
fluidRow(
column(
width = 12,
plotOutput(outputId = ns("grafico"))
)
)
)
}
# Server ------------------------------------------------------------------
conteudo_server <- function(id, base){
moduleServer(id, function(input, output, session){
# browser()
# 3. Filtrar a base em um reactive ou dentro do render plot?
imdb_filtrado <- reactive({
imdb_filtrado <- base |>
dplyr::filter(ano == input$ano)
})
output$grafico <- renderPlot({
# 3. Filtrar a base em um reactive ou dentro do render plot?
# imdb_filtrado <- imdb |>
# dplyr::filter(ano == input$ano)
imdb_filtrado() |>
dplyr::group_by(nota_imdb) |>
dplyr::summarise(receita_tot = sum(receita, na.rm = TRUE)) |>
ggplot2::ggplot() +
ggplot2::geom_point(
ggplot2::aes(
x = nota_imdb,
y = receita_tot
)
)
})
})
}
Created on 2021-12-01 by the reprex package (v2.0.1)
Muito obrigado por qualquer ajuda!
Abraços.