Я нашел рабочее решение, определив несколько UI-функций в модуле.Цель состоит в том, чтобы модуль взял набор данных в качестве входных данных и провел с ним несколько сложных преобразований.Затем я хочу отобразить некоторые визуализации на первой вкладке и несколько кнопок загрузки на второй вкладке.Поскольку обе вкладки ссылаются на одни и те же преобразованные данные, я хочу инкапсулировать их в один и тот же модуль.Пример ниже работает хорошо для меня.Интересно, это плохая практика?
library(shiny)
library(tidyverse)
## module start
results_1_UI <- function(id) {
ns <- NS(id)
tabPanel(
title = "Plot",
plotOutput(ns("testplot"))
)
}
results_2_UI <- function(id) {
ns <- NS(id)
tabPanel(
title = "Export",
downloadButton(ns("download_data"), "Download")
)
}
results <- function(input, output, session, data) {
## do some complicated data transformations
data_transformed <- data
output$testplot <- renderPlot(
{
data_transformed %>%
ggplot(aes(x = Sepal.Length, y = Sepal.Width)) +
geom_point()
})
output$download_data <- downloadHandler(
filename = function() {
paste("data_", Sys.time(), ".csv", sep = "")
},
content = function(file) {
write.csv(data_transformed, file, row.names = FALSE, quote = FALSE, na = "", fileEncoding = "latin1")
},
contentType = "text/csv"
)
}
### module end
ui <- fluidPage(
tabsetPanel(
id = "tabs",
tabPanel(
title = "Tab 1",
"Some text here"
),
results_1_UI(id = "test1"),
results_2_UI(id = "test1")
)
)
server <- function(input, output, session) {
callModule(
module = results,
id = "test1",
data = iris
)
}
shinyApp(ui = ui, server = server)