R 在系统中使用模块
我正在尝试构建一个闪亮的仪表板,并且我希望合并闪亮的模块。在每个选项卡中,应用程序的UI都非常相似,有一个selectInput、dateRangeInput和同一数据集的一个操作按钮。因此,我认为如果我应用模块,代码会大大缩短。我的第一次尝试是使用actionbutton模块,如果我的方法正确,或者您有任何改进建议,我希望得到您的反馈 下面的迷你应用程序的想法是,只有当您单击相应的按钮(按钮1用于绘图1,按钮2用于绘图2)时,数据和绘图才会更新R 在系统中使用模块,r,shiny,R,Shiny,我正在尝试构建一个闪亮的仪表板,并且我希望合并闪亮的模块。在每个选项卡中,应用程序的UI都非常相似,有一个selectInput、dateRangeInput和同一数据集的一个操作按钮。因此,我认为如果我应用模块,代码会大大缩短。我的第一次尝试是使用actionbutton模块,如果我的方法正确,或者您有任何改进建议,我希望得到您的反馈 下面的迷你应用程序的想法是,只有当您单击相应的按钮(按钮1用于绘图1,按钮2用于绘图2)时,数据和绘图才会更新 这是一个小例子,但是考虑一个有20个不同标签的闪
这是一个小例子,但是考虑一个有20个不同标签的闪亮的仪表板,我认为它会使代码更容易阅读,而不是每次只为每个选项卡写按钮UI。类似地,我希望为select_ui和daterange_ui提供类似的功能
ec <- data.frame(
country = c("US", "UK", "Germany", "Spain", "India"),
A = c("1", "2", "2", "3", "3"),
B = c(100, 200, 300, 400, 500)
)
## MODULE
library(shiny)
library(tidyverse)
library(ggplot2)
button_ui <- function(id) {
actionButton(NS(id, "btn"), label = "Apply")
}
button_server <- function(id) {
moduleServer(id, function(input, output, session) {
reactive(input$btn)
})
}
## BUILDING THE APP
ui <- fluidPage(
selectInput(
"choice",
"Select Country:",
multiple = TRUE,
choices = unique(ec$country),
selected = "US"),
button_ui("btn1"),
button_ui("btn2"),
plotOutput("plot1"),
br(),
plotOutput("plot2")
)
server <- function(input, output, session) {
button <- button_server("btn1")
button_a <- button_server("btn2")
dt <- reactive({button()
isolate(
ec %>% filter(country %in% input$choice)
)
})
dt1 <- reactive({button_a()
isolate(
ec %>% filter(country %in% input$choice)
)
})
output$plot1 <- renderPlot({
ggplot(dt(), aes(x = country, y = A)) +
geom_bar(stat = "identity") +
theme_test()
})
output$plot2 <- renderPlot({
ggplot(dt1(), aes(x = country, y = B)) +
geom_bar(stat = "identity") +
theme_test()
})
}
shinyApp(ui, server)
ec您对模块的一般使用是正确的,但我认为您的actionbutton模块太精细了。基本上,您只围绕一个UI元素包装一个模块,因此产生的开销大于有用性。但是,我认为在您的情况下,将selectInput
和绘图输出组合在一个模块中是有意义的。您可以在下面的示例中看到这一点。我还改变了以下几点:
- 我使用
eventReactive
- 我使用闪亮1.5.0中的新模块界面
这似乎更有意义。谢谢你的建议@starja。请允许我问一下,为什么在手头的案例中使用EventResponsive而不是Responsive和isolate?至少在我的案例中,它在第一次单击按钮之前已经显示了绘图。另外,eventReactive
正是提供所需功能的函数:它生成一个被动输出,仅当第一个表达式(操作按钮)的值更改时才会更改。因此,您需要输入更少的代码,通过查看代码,您可以直接推断此反应式的行为(您不必查找隔离语句,在更复杂的代码中,这些语句可能更复杂)。感谢您的解释。这是有道理的
ec <- data.frame(
country = c("US", "UK", "Germany", "Spain", "India"),
A = c("1", "2", "2", "3", "3"),
B = c(100, 200, 300, 400, 500)
)
## MODULE
library(shiny)
library(dplyr)
library(ggplot2)
tab_module_ui <- function(id) {
ns <- NS(id)
tabPanel(
title = paste0("Plot ", id),
selectInput(
ns("choice"),
"Select Country:",
multiple = TRUE,
choices = unique(ec$country),
selected = "US"),
actionButton(ns("btn"), label = "Apply"),
plotOutput(ns("plot"))
)
}
tab_module <- function(id) {
moduleServer(
id,
function(input, output, session) {
dt <- eventReactive(input$btn, {
ec %>% filter(country %in% input$choice)
})
output$plot <- renderPlot({
ggplot(dt(), aes(x = country, y = A)) +
geom_bar(stat = "identity") +
theme_test()
})
}
)
}
## BUILDING THE APP
ui <- fluidPage(
tabsetPanel(
tab_module_ui("plot-1"),
tab_module_ui("plot-2")
)
)
server <- function(input, output, session) {
tab_module("plot-1")
tab_module("plot-2")
}
shinyApp(ui, server)