Приложение RShiny — условия рендеринга таблицы данных

#r #function #user-interface #shiny

#r #функция #пользовательский интерфейс #блестящий

Вопрос:

Целью этой реактивной функции является отображение необработанного starwars набора данных (доступного из dplyr библиотеки) во время первоначального тестирования приложения RShiny.

В текущем сценарии пользователь должен сначала нажать, Run Query чтобы данные появились, затем может перейти к фильтрам, соответствующим образом фильтровать, Run Query снова нажать, чтобы результаты отображались.

Идеальная цель состоит в том, чтобы конечный пользователь сначала отображал данные, затем у пользователя была бы возможность выбирать, какие фильтры они хотят, а затем нажимать Run Query , чтобы результаты отображались соответствующим образом.

Любая помощь будет принята с благодарностью! Спасибо!

 library(DT)
library(shiny)
library(shinydashboard)
library(dplyr)
library(dbplyr)
library(tidyverse)
library(DBI)

ui <- function(request) {
  dashboardPage(
    dashboardHeader(title = "SW Pivot"),
    dashboardSidebar(
      actionButton("runit", "RUN QUERY"),
      hr(),
      h4(HTML("amp;nbsp"), "Filter Data Set"),
      
      uiOutput("hairColorFilter"),
      uiOutput("skinColorFilter")
    ),
    dashboardBody(dataTableOutput("data"))
    
  )
}

data <- starwars

server<-shinyServer(function(input, output, session) {
  
  # Identify Filter Choices -----------------------------------------------
  
  hairColorChoices <- sort(unique(data$hair_color))
  skinColorChoices <- sort(unique(data$skin_color))
  
  # Define User Inputs ----------------------------------------------------
  
  output$hairColorFilter <- renderUI({
    sidebarMenu(
      menuItem(
        text = "Hair Color",
        icon = icon("briefcase"),
        checkboxGroupInput(
          inputId = "hairColorChoices",
          label = NULL,
          choices = hairColorChoices,
          selected = hairColorChoices
        )
      )
    )
  })
  
  output$skinColorFilter <- renderUI({
    sidebarMenu(
      menuItem(
        text = "Skin Color",
        icon = icon("thermometer-half"),
        checkboxGroupInput(
          inputId = "skinColorChoices",
          label = NULL,
          choices = skinColorChoices,
          selected = skinColorChoices
        )
      )
    )
  })
  
  # Table Data --------------------------------------------------------------
  
  filterData <- reactive({
    input$runit

    isolate({
      filterData <- data %>%
        filter(
          hair_color %in% input$hairColorChoices,
          skin_color %in% input$skinColorChoices
        )
    })
  })
  
  output$data <- renderDataTable({
    filterData()
    
  })
})

shinyApp(ui, server)
  

Ответ №1:

Один из способов сделать это — создать reactiveValues объект, который можно показать в начале. Затем eventReactive можно создать отфильтрованные данные. Попробуй это

 server<-shinyServer(function(input, output, session) {
  
  DF1 <- reactiveValues(data=NULL)
  # Identify Filter Choices -----------------------------------------------
  
  hairColorChoices <- sort(unique(data$hair_color))
  skinColorChoices <- sort(unique(data$skin_color))
  
  # Define User Inputs ----------------------------------------------------
  
  output$hairColorFilter <- renderUI({
    sidebarMenu(
      menuItem(
        text = "Hair Color",
        icon = icon("briefcase"),
        checkboxGroupInput(
          inputId = "hairColorChoices",
          label = NULL,
          choices = hairColorChoices,
          selected = hairColorChoices
        )
      )
    )
  })
  
  output$skinColorFilter <- renderUI({
    sidebarMenu(
      menuItem(
        text = "Skin Color",
        icon = icon("thermometer-half"),
        checkboxGroupInput(
          inputId = "skinColorChoices",
          label = NULL,
          choices = skinColorChoices,
          selected = skinColorChoices
        )
      )
    )
  })
  
  # Table Data --------------------------------------------------------------
  
  filterData <- eventReactive(input$runit, {
    
    isolate({
      filterData <- data %>%
        filter(
          hair_color %in% input$hairColorChoices,
          skin_color %in% input$skinColorChoices
        )
    })
  })
  
  observe({
    DF1$data <- starwars
    if (!is.null(filterData())) DF1$data <- filterData()
  })
  
  output$data <- renderDataTable({
    DF1$data
  })
})

shinyApp(ui, server)
  

Комментарии:

1. Это потрясающе, спасибо! Есть ли способ использовать «реактивную» функцию для создания отфильтрованного набора данных?

2. Если ваша цель — обновить таблицу при нажатии кнопки «Выполнить запрос», event reactive этого будет достаточно. Однако, если вы хотите обновлять таблицу всякий раз, когда пользователь изменяет выбор (без нажатия кнопки ВЫПОЛНИТЬ запрос), измените значение eventReactive на reactive . Пожалуйста, обратите внимание, что filteredData является реактивным.

Ответ №2:

Я бы попробовал это вместо того, что у вас есть # Table Data . Не забудьте последнее }) после закрытия server . В моих блестящих приложениях я использую observeEvent для этого типа операций. Переведено на слова…Когда я нажимаю runit кнопку, я хочу отфильтровать data , используя my input s, а затем передать эти данные на DT вывод.

 observeEvent(input$runit, {
    
      filterData <- data %>%
        filter(
          hair_color %in% isolate(input$hairColorChoices),
          skin_color %in% isolate(input$skinColorChoices)
        )
    
  output$data <- renderDataTable({
    DT::datatable(filterData)
  })

})