【问题标题】:Make renderUI an input for observeEvent使 renderUI 成为 observeEvent 的输入
【发布时间】:2019-12-16 01:33:13
【问题描述】:

正如标题所示,我希望创建一个动态创建的 UI 对象(使用 renderUI),以后可以在 Shiny App 中进一步操作。

在下面的代表中,我有一个玩具应用程序,它允许用户根据萼片宽度过滤iris 数据集。根据用户选择的范围,我会生成一个包含该萼片宽度范围内所有独特物种的复选框列表。

我的问题是:如何让应用程序告诉我在用户过滤表格后选择了哪个物种的复选框?例如,在默认的应用程序设置下,当萼片宽度范围在 1 到 2 之间时,只有一种物种满足过滤器要求(杂色)。当用户选中 versicolor 框时,我希望应用更新以告诉我已选择 versicolor。

同样,当萼片宽度范围更大时(然后动态生成的复选框列表中包含更多物种),我希望 UI 再次更新以告诉我选择了哪个物种(1、2 或所有 3 个物种)。

我脑海中的基本工作流程是:

(1) 用户过滤数据集 (2) 显示基于过滤器的表格更新 (3) 应用生成唯一物种的复选框列表 (4) 用户点击物种,物种名称显示在屏幕上。

library(shiny)
library(DT)
library(dplyr)

ui <- basicPage(

  fluidRow(
    uiOutput("ui"),
    sliderInput("slider", "Sepal Width", min = 0, max=20, value=c(1:2)),
    tableOutput("data")

  ),

)



server <- function(input, output){

  data("iris")

  filtered<-reactive({

    iris %>% filter(`Sepal.Width` %in% input$slider[1]:input$slider[2])


  })

  output$data<-renderTable({

    filtered()

  })

  output$ui<-renderUI({

    species<-filtered() 
    checkboxGroupInput(inputId = 'occurence_checkboxes', label = 'Species', choices = unique(species$Species))

  })




}

shinyApp(ui, server)

【问题讨论】:

  • 您是否只是希望用户选择的物种名称出现在屏幕上?还是由用户对所选物种进行过滤?
  • 最终目标是,一旦物种被过滤,下游代码将提取这些物种的观察记录并将其显示在地图上。由于这将在计算上相当昂贵,因此我不希望代码运行,除非用户明确想要查看这些物种的分布位置(通过选择所需的物种)。我希望能澄清一些事情。

标签: r shiny shiny-reactivity


【解决方案1】:

这应该可以解决问题:

library(shiny)
library(dplyr)

ui <- basicPage(
  fluidRow(
    uiOutput("ui"),
    sliderInput("slider", "Sepal Width", min = 0, max=20, value = 1:2),
    tableOutput("data")
  )
)

server <- function(input, output){
  get_width_filter <- reactive({
     iris %>% filter(between(Sepal.Width, input$slider[1], input$slider[2]))
  })

  get_ovl_filter <- reactive({
     get_width_filter() %>%
       filter(Species %in% input$occurence_checkboxes)
  })

  output$data <- renderTable({
    get_ovl_filter()
  })

  output$ui <- renderUI({
    choices <-  get_width_filter() %>% pull(Species) %>% unique()
    checkboxGroupInput("occurence_checkboxes", 
                       "Species", 
                       choices = choices, 
                       selected = choices)
  })
}

shinyApp(ui, server)

说明

我们需要将filtered 例程分成两部分:第一部分仅应用宽度过滤器,另一部分还包含物种过滤器。您可以通过在 renderUI 函数中使用的名称访问动态创建的复选框。我们必须拆分响应式过滤器的原因是,否则renderUI 将依赖于我们想要避免的复选框本身。

更新

我刚刚读到您只是想返回复选框的值而不是使用它进行过滤。不过我想现在应该很清楚了,只要在需要的地方使用input$occurence_checkboxes

【讨论】:

  • 感谢您的回复,但我认为这并没有达到我的预期。该应用程序的最终目标是,一旦物种被过滤(使用滑块),下游代码将提取这些物种的观察记录并将其显示在地图上。由于这将在计算上相当昂贵,因此我不希望代码运行,除非用户明确想要查看这些物种的分布位置(通过使用动态生成的复选框选择所需的物种)。因此,我需要为每个复选框选择触发一个唯一事件。
  • 啊,刚刚看到你关于input$occurrence_checkboxes的更新。让我快速玩一下,我会回复你这是否提供了必要的功能。干杯!
  • 嗨,thothal,如果您有时间,您能否编辑您的答案代码以演示您在“更新”下提到的功能(并响应我的 cmets 对您的回答)。我尝试以我认为正确的方式使用input$occurrence_checkboxes……但我无法让代码正常工作。提前致谢。
  • 没关系,这是我的错字!现在都在工作。接受你的回答。感谢您(快速)的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-20
  • 2019-06-07
  • 2021-09-05
  • 2020-05-24
  • 2021-06-06
  • 2017-06-29
  • 2021-11-15
相关资源
最近更新 更多