闪亮模块:在多个元素中使用 SliderInput

Shiny Modules: Use SliderInput in multiple Elements

我是 Shiny Modules 的新手,我想在(至少)两个不同的元素中使用 sliderInput 中的 input。因此我创造了一点reprex。我想要一个带有垂直线的直方图来显示主面板中的滑块值和 table,应该根据相同的滑块值对其进行过滤。 因为实际上我有很多滑块,所以我认为 Shiny Modules 是构建和减少代码量的好方法。

不幸的是,我有一个错误,已经尝试了各种方法但找不到解决它的方法。我无法访问 table 和直方图中的滑块值。预先感谢您的帮助。

library(shiny)
library(tidyverse)

ui_slider <- function(id, height = 140, label = "My Label") {
  sliderInput(inputId = NS(id, "slider"), label = label, min = 0, max = 5, value = 1)
}

server_slider <- function(id) {
  moduleServer(id, function(input, output, session) {
    reactive(get(input$slider))
  })
}


ui_hist <- function(id, height = 140) {
  plotOutput(outputId = NS(id, "hist_plot"), height = height)
}

server_hist <- function(id, df, col, slider_value) {
  stopifnot(is.reactive(slider_value))
  
  moduleServer(id, function(input, output, session) {
    output$hist_plot <- renderPlot({
      df %>%
        ggplot(aes_string(x = col)) +
        geom_histogram() +
        geom_vline(aes(xintercept = slider_value()))
    })
  })
}

ui <- fluidPage(
  titlePanel("My Dashboard"),
  sidebarLayout(
    sidebarPanel(
      ui_hist("gear"),
      ui_slider("gear", label = "Gear"),
      ui_hist("carb"),
      ui_slider("carb", label = "Carb")
    ),
    mainPanel(
      tableOutput("table")
    )
  )
)

server <- function(input, output, session) {
  gear_val <- server_slider("gear")
  carb_val <- server_slider("carb")
  
  server_hist(
    id = "gear",
    df = tibble(mtcars),
    col = "gear",
    slider_value = gear_val
  )
  
  server_hist(
    id = "carb",
    df = tibble(mtcars),
    col = "carb",
    slider_value = carb_val
  )
  
  output$table <- renderTable({
    tibble(mtcars) %>%
      filter(gear > gear_val()) %>%
      filter(carb > carb_val())
  })
}

# Run the application
shinyApp(ui = ui, server = server)

reprex package (v2.0.1)

于 2022-04-22 创建

您在滑块模块服务器功能中不必要地使用了 get()。删除它应该可以解决问题。

server_slider <- function(id) {
  moduleServer(id, function(input, output, session) {
    reactive(input$slider)
  })
}