【问题标题】:Shiny: dynamic dataframe construction; renderUI, observe, reactiveValuesShiny:动态数据框构建; renderUI,观察,reactiveValues
【发布时间】:2017-04-13 09:21:41
【问题描述】:

我认为如何使用 Shiny 的 renderUI 功能动态地对数据进行子集化的问题经常出现,但我很难理解何时使用 renderUI(带有 uiOutput)而不是其他功能,包括观察、反应式、反应式值甚至条件面板。

我想构建一个完全交互式的数据框,其中每个选择都会影响您在其他输入中可以选择的内容。对于这个例子,我们将有一个 selectInput(单)、selectInput(多)和一个滑块输入(带最大值和最小值)。

主要选择类别 1 可以是类别 1 或“全部”中的任何值。通过选择类别 1 中的某些内容,您反过来会影响类别 2 中可以显示的内容以及滑块上的值范围。通过首先选择类别 2,您可以限制类别 1 的选项以及滑块中的值(始终表示子集的最大值和最小值)。从滑块输入开始,如果类别 1 和类别 2 的数据都不在您指定的范围内,则它们将受到限制。

注意我将合并一个“重置”操作按钮,以将数据框重置为应用程序初始化时的状态。

尝试使用一些虚拟数据,但我没有设法开始工作。这将按类别 1 进行子集化并更新滑块,但更改类别 2 不会覆盖呈现的表格;

require(shiny)

    data <- data.frame(Category1 = rep(letters[1:3],each=15),
                       Info = paste("Text info",1:45),
                       Category2 = sample(letters[15:20],45,replace=T),
                       Size = sample(1:100, 45),
                       MoreStuff = paste("More Stuff",1:45))

ui <- fluidPage(

  titlePanel("Test Explorer"),

  sidebarLayout(
    sidebarPanel(
      uiOutput("category1"),
      uiOutput("category2"),
      uiOutput("sizeslider")
      ),
    mainPanel(
      tableOutput("table")
    )
  )
)

server <- function(input, output,session) {

  df_subset <- reactive({
    if(input$cat1=="All") {df_subset <- data}
    else{df_subset <- data[data$Category1==input$cat1,]}

  })

  df_subset1 <- reactive({
    if(is.null(input$cat2)){df_subset()} else {df_subset()[df_subset()$Category2==input$cat2,]}
  })

  output$category1 <- renderUI({
    selectizeInput('cat1', 'Choose Cat 1', choices = c("All",sort(as.character(unique(data$Category1)))),selected = "All")
  })

  output$category2 <- renderUI({
    selectizeInput('cat2', 'Choose Cat 2 (optional):', choices = sort(as.character(unique(df_subset1()$Category2))), multiple = TRUE,options=NULL)
  })

  output$sizeslider <- renderUI({
    sliderInput("size", label = "Size Range", min=min(df_subset1()$Size), max=max(df_subset1()$Size), value = c(min(df_subset1()$Size),max(df_subset1()$Size)))
  })

  output$table <- renderTable({
    df_subset1()
  })

}

shinyApp(ui, server)

【问题讨论】:

    标签: r dataframe shiny


    【解决方案1】:

    了解正在发生的事情有点棘手,但是,这是您想要的吗?注意将reactive 更改为eventReactive,因此它专门绑定到input。我还使用%in% 运算符为您的selectizeInput 进行多项选择

    编辑:在您的第一个代码中,您甚至不使用滑块,我将其添加到过滤中

    #rm(list = ls())
    library(shiny)
    
    data <- data.frame(Category1 = rep(letters[1:3],each=15),
                       Info = paste("Text info",1:45),
                       Category2 = sample(letters[15:20],45,replace=T),
                       Size = sample(1:100, 45),
                       MoreStuff = paste("More Stuff",1:45))
    
    ui <- fluidPage(
    
      titlePanel("Test Explorer"),
      sidebarLayout(
        sidebarPanel(
          uiOutput("category1"),
          uiOutput("category2"),
          uiOutput("sizeslider")
        ),
        mainPanel(
          tableOutput("table")
        )
      )
    )
    
    server <- function(input, output,session) {
    
      output$category1 <- renderUI({
        selectizeInput('cat1', 'Choose Cat 1', choices = c("All",sort(as.character(unique(data$Category1)))),selected = "All")
      })
    
      df_subset <- eventReactive(input$cat1,{
        if(input$cat1=="All") {df_subset <- data}
        else{df_subset <- data[data$Category1 == input$cat1,]}
      })
    
      df_subset1 <- reactive({
        if(is.null(input$cat2)){df_subset()} else {df_subset()[df_subset()$Category2 %in% input$cat2,]}
      })
    
      output$category2 <- renderUI({
        selectizeInput('cat2', 'Choose Cat 2 (optional):', choices = sort(as.character(unique(df_subset()$Category2))), multiple = TRUE,options=NULL)
      })
    
      output$sizeslider <- renderUI({
        sliderInput("size", label = "Size Range", min=min(df_subset1()$Size), max=max(df_subset1()$Size), value = c(min(df_subset1()$Size),max(df_subset1()$Size)))
      })
    
      df_subset2 <- reactive({
        if(is.null(input$size)){df_subset1()} else {df_subset1()[df_subset1()$Size >= input$size[1] & df_subset1()$Size <= input$size[2],]}
      })
    
      output$table <- renderTable({
        df_subset2()
      })
    }
    
    shinyApp(ui, server)
    

    【讨论】:

    • 不幸的是,这并没有完全做到这一点,滑块仍然对输出没有影响,并且 category2 选项不会更新呈现的表(尽管您可以看到它在它立即消失之前做了一些事情)
    • 你甚至不使用示例代码中的滑块,至少下次尝试一下
    • 感谢您异常积极的帮助。我认为这是一个可以理解的疏忽,而且只是一个疏忽,错过了滑块,代码中发生了很多事情。还是谢谢你。
    猜你喜欢
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 2018-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-16
    相关资源
    最近更新 更多