在一个闪亮的模块中创建多个选项卡
Create multiple tabs within one shiny module
我正在使用 tabsetPanel,现在我想创建一个模块,向该面板添加多个选项卡。这是我的示例代码:
library(shiny)
library(tidyverse)
resultlistUI <- function(id) {
ns <- NS(id)
tabPanel(
title = "Result1",
"Some text here 2"
)
tabPanel(
title = "Result2",
"Some text here 3"
)
}
resultlist <- function(input, output, session) {
}
ui <- fluidPage(
tabsetPanel(
id = "tabs",
tabPanel(
title = "Tab 1",
"Some text here"
),
resultlistUI(id = "resultlist1")
)
)
server <- function(input, output, session) {
}
shinyApp(ui = ui, server = server)
我首先想知道为什么我不能简单地用逗号分隔两个选项卡。当我执行代码时,只有我的第二个选项卡 "Result2" 被添加到 tabsetPanel。我也尝试使用 tagList 但随后显示了 none 个选项卡。我做错了什么?
编辑:
添加了完整的最小可重现示例 - 仅显示主应用程序的第一个选项卡和模块的第二个选项卡。
问题可能来自函数 tabsetPanel 使用其参数的方式。
该函数需要用逗号分隔的 tabPanel。
在做你正在做的事情时,你在一个参数中提供了两个 tabPanel。
因此,您必须想出一种方法,让您可以为每个参数提供一个选项卡。通过从您的模块返回一个列表并使用函数 do.call 您可以实现这一点。
library(shiny)
library(tidyverse)
resultlistUI <- function(id) {
ns <- NS(id)
list(
tabPanel(
title = "Result1",
"Some text here 2"
),
tabPanel(
title = "Result2",
"Some text here 3"
))
}
resultlist <- function(input, output, session) {
}
ui <- fluidPage(
do.call(tabsetPanel,
list(id = 'tabs',
tabPanel(
title = "Tab 1",
"Some text here"
)) %>% append(resultlistUI(id = "resultlist1")))
)
server <- function(input, output, session) {
}
shinyApp(ui = ui, server = server)
此外,不确定你的模块应该做什么,但你没有在服务器内部调用 resultList,你需要在你的应用程序中包含这两个部分,否则模块将无法工作。
我通过在模块中定义多个 UI-functions 找到了可行的解决方案。目的是该模块将数据集作为输入并对其进行一些复杂的转换。然后我想在第一个选项卡上显示一些可视化效果,并在第二个选项卡上显示一些下载按钮。由于两个选项卡都引用相同的转换数据,我想将它们封装在同一个模块中。下面的例子对我来说很好用。我想知道这是不是不好的做法?
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)
我正在使用 tabsetPanel,现在我想创建一个模块,向该面板添加多个选项卡。这是我的示例代码:
library(shiny)
library(tidyverse)
resultlistUI <- function(id) {
ns <- NS(id)
tabPanel(
title = "Result1",
"Some text here 2"
)
tabPanel(
title = "Result2",
"Some text here 3"
)
}
resultlist <- function(input, output, session) {
}
ui <- fluidPage(
tabsetPanel(
id = "tabs",
tabPanel(
title = "Tab 1",
"Some text here"
),
resultlistUI(id = "resultlist1")
)
)
server <- function(input, output, session) {
}
shinyApp(ui = ui, server = server)
我首先想知道为什么我不能简单地用逗号分隔两个选项卡。当我执行代码时,只有我的第二个选项卡 "Result2" 被添加到 tabsetPanel。我也尝试使用 tagList 但随后显示了 none 个选项卡。我做错了什么?
编辑: 添加了完整的最小可重现示例 - 仅显示主应用程序的第一个选项卡和模块的第二个选项卡。
问题可能来自函数 tabsetPanel 使用其参数的方式。 该函数需要用逗号分隔的 tabPanel。
在做你正在做的事情时,你在一个参数中提供了两个 tabPanel。
因此,您必须想出一种方法,让您可以为每个参数提供一个选项卡。通过从您的模块返回一个列表并使用函数 do.call 您可以实现这一点。
library(shiny)
library(tidyverse)
resultlistUI <- function(id) {
ns <- NS(id)
list(
tabPanel(
title = "Result1",
"Some text here 2"
),
tabPanel(
title = "Result2",
"Some text here 3"
))
}
resultlist <- function(input, output, session) {
}
ui <- fluidPage(
do.call(tabsetPanel,
list(id = 'tabs',
tabPanel(
title = "Tab 1",
"Some text here"
)) %>% append(resultlistUI(id = "resultlist1")))
)
server <- function(input, output, session) {
}
shinyApp(ui = ui, server = server)
此外,不确定你的模块应该做什么,但你没有在服务器内部调用 resultList,你需要在你的应用程序中包含这两个部分,否则模块将无法工作。
我通过在模块中定义多个 UI-functions 找到了可行的解决方案。目的是该模块将数据集作为输入并对其进行一些复杂的转换。然后我想在第一个选项卡上显示一些可视化效果,并在第二个选项卡上显示一些下载按钮。由于两个选项卡都引用相同的转换数据,我想将它们封装在同一个模块中。下面的例子对我来说很好用。我想知道这是不是不好的做法?
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)