How to efficiently process data with multiple filters in a brilliant application

We have created a brilliant application in which either the user can download a large data set (RData file more than 200 MB), or they can choose one of them. Then there are three different tabs where the user can filter the data (tab for numbers, tab for categorical categories).

So, I currently have 3 reactivefunctions for this purpose. But the disadvantage is that the object is stored three times in memory. Is there a more efficient way to do this?

The following is an example of a simplified example: Note: in this application you see only 1 filter per tab. it usually looks more like this:

My_Filtered_Data[Species %in% input$filter1 &
                   x %in% input$x &
                   y %in% input$y &
                   z %in% input$z] #etc.

I watched reactiveValues, but could not find how it works. The reason I don’t want to have it at 1 reactiveis because every time I change one of the filters on one of the sheets, the whole filtering process starts again, and it takes a lot of time. I would prefer to have one dataset that will only be updated with the filter that is in use at that time. That's why I included various reactive agents

## app.R ##
library(shinydashboard)
library(data.table)
CustomHeader <- dashboardHeader(title='datatest')
iris<-iris

ui <- function(request) {
  dashboardPage(
    CustomHeader,
    ## Sidebar content
    dashboardSidebar(
      sidebarMenu(
        menuItem("filter1 & Import", tabName = "filter1", icon = icon("dashboard")),
        menuItem("filter2", tabName = "filter2", icon = icon("th")),
        menuItem("filter3", tabName = "filter3", icon = icon("th"))
      )
    ),
    ## Body content
    dashboardBody(
      tabItems(
        # First tab content
        tabItem(tabName = "filter1",
                fluidRow(box(width = 3,
                             selectInput(inputId = 'filter1','filter1:species',choices = unique(iris$Species))))

        ),

        tabItem(tabName = "filter2",
                fluidRow(box(width = 3,
                             sliderInput(inputId = 'filter2','filter2:Max.Sepal.Length',min = 0,max = 10,value = 10)
                                         ))

        ),
        tabItem(tabName = "filter3",
                fluidRow(box(width = 3,
                             sliderInput(inputId = 'filter3','filter3:Min.Sepal.Width',min = 0,max = 10,value = 0)
                             ),
                         box(width=9,dataTableOutput('mydata')))

        )
        )
      )
    )

}
server <- function(input, output) {
  My_Uploaded_Data <- reactive({
    My_Uploaded_Data<-data.table(iris)
    My_Uploaded_Data
  })

  My_Filtered_Data <- reactive({
    My_Filtered_Data<-My_Uploaded_Data()
    My_Filtered_Data[Species %in% input$filter1]
  })

  My_Filtered_Data2 <- reactive({
    My_Filtered_Data2<-My_Filtered_Data()
    My_Filtered_Data2[Sepal.Length < input$filter2]
  })  

  My_Filtered_Data3 <- reactive({
    My_Filtered_Data3<-My_Filtered_Data2()
    My_Filtered_Data3[Sepal.Width > input$filter3]
  })  
  output$mydata<-renderDataTable({
    My_Filtered_Data3()
  })

}
shinyApp(ui, server)

I was hoping something like this would work in reactiveValues

 react_vals <- reactiveValues(data = NULL)
  observe(react_vals$data <- MyLoadedData())
  observe(react_vals$data <- react_vals$data[Species %in% input$filter1])
  observe(react_vals$data <- react_vals$data[Sepal.Length < input$filter2])
  observe(react_vals$data <- react_vals$data[Sepal.Width > input$filter3])

EDIT: I would also like to include bookmarks: https://shiny.rstudio.com/articles/advanced-bookmarking.html and it seems to you what you need reactiveValuesfor this. Therefore, another reason for me to move away from all these reactives/eventReactive

+4
2

. , ; . , .

iris data.table:

library(shinydashboard)
library(data.table)
CustomHeader <- dashboardHeader(title = 'datatest')
iris <- iris
setDT(iris)  # Added

:

server <- function(input, output) {
  filter1_rows <- reactive({
    iris[Species %in% input$filter1,   which = TRUE]
  })
  filter2_rows <- reactive({
    iris[Sepal.Length < input$filter2, which = TRUE]
  })
  filter3_rows <- reactive({
    iris[Sepal.Width > input$filter3,  which = TRUE]
  })
  output$mydata <- renderDataTable({
    final_rows <- intersect(filter1_rows(), filter2_rows())
    final_rows <- intersect(final_rows,     filter3_rows())
    iris[final_rows]
  })
}

which data.table[...], , .

+4

, / . " ". , : "" .

, , . , , . . , (.. ), , reactiveValues.

, , . " ", .

+2

Source: https://habr.com/ru/post/1682378/


All Articles