在Shiny中选择表格的列

时间:2017-12-05 15:23:18

标签: r shiny

我想在开头添加一个新类别,它将选择表格的列。我无法将变量与应用程序中的其他元素组合在一起。有人可以向我解释我做错了什么吗?正如您在图形程序中看到的那样效果不佳。 enter image description here

我的代码:

 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(
                    selectizeInput(
                      "show_vars",
                      "Columns to show:",
                      choices = colnames(data),
                      multiple = TRUE,
                      selected = c("Category1", "Info", "Category2")
                    ),
                    uiOutput("category1"),
                    uiOutput("category2"),
                    uiOutput("sizeslider")
                  ),
                  mainPanel(tableOutput("table"))
                ))

server <- function(input, output, session) {
  data2 <- reactive({
    req(input$table)
    if (input$table == "All") {
      return(data)
    }
    data[, names(data) %in% input$show_vars]
  })

  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)

1 个答案:

答案 0 :(得分:1)

您的代码几乎没有问题

  1. 您在data2()中存储了列选择的无效值,并显示了表df_subset2()。与您的代码一样,当您添加列并选择Cat1下拉列表时,列会发生更改,因为其值取决于data.react
  2. 避免使用data等通用名称来存储数据。有时会干扰R基本名称
  3. 当您希望UI上的更改能够反映时,您需要使用ObserveEventeventReactive
  4. 以下是我修复的内容,您可以相应更改。

    1. 添加了提交按钮
    2. 将输入选择代码包装到ObserveEvent 这样,只有在单击“提交”按钮时才会显示数据。
    3. 这是代码。

      library(shiny)
      
      data.input <- 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.r

      ui <- fluidPage(titlePanel("Test Explorer"),
                      sidebarLayout(
                        sidebarPanel(
                          selectizeInput(
                            "show_vars",
                            "Columns to show:",
                            choices = colnames(data.input),
                            multiple = TRUE,
                            selected = c("Category1", "Info", "Category2")
                          ),
                          actionButton("button", "An action button"),
                          uiOutput("category1"),
                          uiOutput("category2"),
                          uiOutput("sizeslider")
                        ),
                        mainPanel(tableOutput("table"))
                      ))
      

      <强> server.r

      server <- function(input, output, session) {
        data.react <- eventReactive(input$button, {
          data.input[, input$show_vars]
        })
        observeEvent(input$button, {
          output$category1 <- renderUI({
            data.sel <- data.react()
            selectizeInput('cat1',
                           'Choose Cat 1',
                           choices = c("All", sort(as.character(
                             unique(data.sel$Category1)
                           ))),
                           selected = "All")
          })
      
          df_subset <- eventReactive(input$cat1, {
            data.sel <- data.react()
            if (input$cat1 == "All") {
              data.sel
            }
            else{
              data.sel[data.sel$Category1 == input$cat1,]
            }
          })
      
          output$category2 <- renderUI({
            selectizeInput(
              'cat2',
              'Choose Cat 2 (optional):',
              choices = sort(as.character(unique(
                df_subset()$Category2
              ))),
              multiple = TRUE,
              options = NULL
            )
          })
      
          df_subset1 <- reactive({
            if (is.null(input$cat2)) {
              df_subset()
            } else {
              df_subset()[df_subset()$Category2 %in% input$cat2,]
            }
          })
      
          output$sizeslider <- renderUI({
            sliderInput(
              "size",
              label = "Size Range",
              min = min(data.input$Size),
              max = max(data.input$Size),
              value = c(min(data.input$Size), max(data.input$Size))
            )
          })
      
          df_subset2 <- reactive({
            if (is.null(input$size)) {
              df_subset1()
            } else {
              df_subset1()[data.input$Size >= input$size[1] &
                             data.input$Size <= input$size[2],]
            }
          })
          output$table <- renderTable({
            df_subset2()
      
          })
        })
      }
      
      shinyApp(ui, server)