r - 如何在 Shiny 的应用程序中使用多个过滤器有效处理数据

标签 r memory shiny data.table reactive-programming

我们创建了一个 Shiny 的应用程序,用户可以上传大型数据集(超过 200MB 的 RData 文件),也可以从我们这里选择一个。然后,用户可以在三个不同的选项卡中过滤数据(数字选项卡、类别选项卡)

所以目前我有 3 个 reactive 函数来达到这个目的。但缺点是该对象在内存中保存了 3 次。有没有更有效的方法来做到这一点?

请在下面找到一个简化的示例应用程序: 注意:在此应用程序中,每个选项卡只能看到 1 个过滤器。通常它更像是这样的:

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

我正在查看 reactiveValues 但无法真正找到它是如何工作的。 我不想将其置于 1 reactive 中的原因是,每次我更改其中一张纸上的其中一个过滤器时,整个过滤过程都会重新开始,这非常耗时。我希望拥有一个仅使用当时使用的过滤器进行更新的数据集。这就是我包含不同 react 的原因

## 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)

我希望像这样的东西可以在 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])

编辑:我还想包含书签:https://shiny.rstudio.com/articles/advanced-bookmarking.html看来你需要 reactiveValues 为此。因此,我放弃所有这些 reactives/eventReactive

的另一个原因

最佳答案

无需将数据集存储在 react 变量中,只需存储符合条件的行即可。这样,每个无功值仅在滤波器发生变化时才被替换;它们没有联系在一起。输出仅使用通过所有过滤器的行。

在程序顶部,将 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]
  })
}

这使用了 data.table[...] 中经常被忽视的 which 参数,这意味着只应返回子集表的行号。

关于r - 如何在 Shiny 的应用程序中使用多个过滤器有效处理数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45344812/

相关文章:

C ,关于指针(或指向指针的指针?)、** 和 malloc

r Shiny -uiOutput未在menuItem内呈现

r - 使用按钮扩展保留 Excel 中的数字格式

html - R Shiny selectedInput inside renderDataTable 细胞

memory - Rot13 实现 : error in translate_string function

r - 通过 R 保持保护(或重新保护)导入的 Excel 工作簿的某些列

R:带有矢量模式的 agrep

r - 如何在 R Shiny App 中的 div 内添加按钮

jQuery 元素已从 DOM 中删除,但似乎存储在内存中?

css - DT Shiny 不同的自定义列标题按列