在闪亮的应用程序中过滤数据,但在更新表时将值保留在 selectInput 中

2024-04-21

我有一个闪亮的应用程序,要求用户上传一个文件(带有数据的表格文件),然后将该文件呈现到一个表中,用户可以根据numericInput, selectInput, and textAreaInput。用户必须选择过滤器,然后按下按钮才能过滤表。

没有顺序过滤,即用户可以填充所有过滤器或仅填充一个。每次用户选择一个过滤器时,其他过滤器的值都会更新(selectInput输入),这就是我想要的行为。然而,一旦Filter按钮被按下,我看不到以前的选择,也无法重置过滤器。

我想要实现的是在更新过滤器时保持实际行为,即一旦我选择一个过滤器并按下另一个过滤器按钮selectInput选择会自动更新,BUT我想跟踪过滤器的选择,以便用户可以看到他/她选择的过滤器。这正是我所期待的,但每次我按下按钮Filter似乎过滤器选项卡再次呈现。

这是我的应用程序,

library(shiny)
library(vroom)
library(dplyr)
library(shinycssloaders)
library(shinydashboard)
library(shinydashboardPlus)
library(tidyr)


header <- dashboardHeader()

sidebar <- dashboardSidebar(width = 450,

  sidebarMenu(id="tabs", 
    menuItem("Filtros", tabName="filtros", icon = icon("bar-chart-o")),
      uiOutput("filtros")

  )
)

body <- dashboardBody(

  tabItems(
    tabItem(tabName="filtros",
          fluidRow(
          column(12,dataTableOutput("tabla_julio") %>% withSpinner(color="#0dc5c1"))
        )
    )  
   )
 )

ui <- dashboardPagePlus(enable_preloader = TRUE, sidebar_fullCollapse = TRUE, header, sidebar, body)

server = function(input, output, session) {

    #Create the choices for sample input
    vals <- reactiveValues(data=NULL)
    vals$data <- iris



  output$filtros <- renderUI({

    datos <- vals$data
      conditionalPanel("input.tabs == 'filtros'",
        tagList(        
            div(style="display: inline-block;vertical-align:top; width: 221px;",numericInput(inputId="Sepal.Length", label="Sepal.Length", value=NA, min = NA, max = NA, step = NA)),                      
            div(
              div(style="display: inline-block;vertical-align:top; width: 224px;", selectInput(inputId = "Species", label = "Species", width = "220",  choices=unique(datos$Species), 
              selected = NULL, multiple = TRUE, selectize = TRUE, size = NULL))
              )
            ),
            actionButton("filtrar", "Filter")
          )
    })

# create reactiveValues

  vals <- reactiveValues(data=NULL)
  vals$data <- iris


# Filter data

observeEvent(input$filtrar, {

      tib <- vals$data

      if (!is.na(input$Sepal.Length)){
        tib <- tib %>% dplyr::filter(!Sepal.Length >= input$Sepal.Length)
        print(head(tib))
      } else { tib <- tib }

      # Filter
      if (!is.null(input$Species)){
        toMatch <- paste0("\\b", input$Species, "\\b")
        matches <- unique(grep(paste(toMatch,collapse="|"), tib$Species, value=TRUE))
        tib <- tib %>% dplyr::filter(Species %in% matches)
      } else { tib <- tib}

      tib -> vals$data
      print(head(tib, n=15))

    })


  # Reactive function creating the DT output object
  output$tabla_julio <- DT::renderDataTable({        
      DT::datatable(vals$data) 
    })

}

shinyApp(ui, server)


另一个更新:

library(shiny)
library(vroom)
library(dplyr)
library(shinycssloaders)
library(shinydashboard)
library(shinydashboardPlus)
library(tidyr)

header <- dashboardHeader()

sidebar <- dashboardSidebar(width = 450,
                            sidebarMenu(id = "tabs",
                                        menuItem(
                                          "Filtros",
                                          tabName = "filtros",
                                          icon = icon("bar-chart-o")
                                        ),
                                        uiOutput("filtros")
                            ))

body <- dashboardBody(tabItems(tabItem(tabName = "filtros",
                                       fluidRow(
                                         column(12,
                                                DT::dataTableOutput("tabla_julio") # %>% withSpinner(color = "#0dc5c1")
                                         )
                                       ))))

ui <-
  dashboardPagePlus(
    enable_preloader = FALSE,
    sidebar_fullCollapse = TRUE,
    header,
    sidebar,
    body
  )

server = function(input, output, session) {
  
  # Create the choices for sample input
  vals <- reactiveValues(data = iris, filtered_data = iris)
  
  output$filtros <- renderUI({
    datos <- isolate(vals$data)
    conditionalPanel(
      "input.tabs == 'filtros'",
      tagList(
        div(
          style = "display: inline-block;vertical-align:top; width: 221px;",
          numericInput(
            inputId = "SepalLength",
            label = "Sepal.Length",
            value = NA,
            min = NA,
            max = NA,
            step = NA
          )
        ),
        div(
          div(
            style = "display: inline-block;vertical-align:top; width: 224px;",
            selectInput(
              inputId = "Species",
              label = "Species",
              width = "220",
              choices = unique(isolate(datos$Species)),
              selected = NULL,
              multiple = TRUE,
              selectize = TRUE,
              size = NULL
            )
          )
        )
      ),
      actionButton("filtrar", "Filter", style = "width: 100px;"),
      actionButton("reset", "Reset", style = "width: 100px;")
    )
  })
  
  
  # Filter data
  observeEvent(input$filtrar, {
    tib <- vals$data
    
    if (!is.na(input$SepalLength)) {
      tib <- tib %>% dplyr::filter(Sepal.Length < input$SepalLength)
      print(head(tib))
    } else {
      tib
    }
    
    # Filter
    if (!is.null(input$Species)) {
      tib <- tib %>% dplyr::filter(Species %in% input$Species)
    } else {
      tib
    }
    
    print(head(tib, n = 15))
    
    vals$filtered_data <- tib
    
    updateSelectInput(session, inputId = "Species", selected = input$Species, choices = unique(vals$filtered_data$Species))
    
  })
  
  observeEvent(input$reset, {
    updateNumericInput(session, inputId = "SepalLength", value = NA)
    updateSelectInput(session, inputId = "Species", selected = "")
  })
  
  # Reactive function creating the DT output object
  output$tabla_julio <- DT::renderDataTable({
    DT::datatable(vals$filtered_data)
  }, server = FALSE)
  
}

shinyApp(ui, server)

Update:我想这就是你所追求的。最重要的一步是isolate输入在renderUI因此它们不会在每次输入更改时重新渲染。

library(shiny)
library(vroom)
library(dplyr)
library(shinycssloaders)
library(shinydashboard)
library(shinydashboardPlus)
library(tidyr)

header <- dashboardHeader()

sidebar <- dashboardSidebar(width = 450,
                            sidebarMenu(id = "tabs",
                                        menuItem(
                                          "Filtros",
                                          tabName = "filtros",
                                          icon = icon("bar-chart-o")
                                        ),
                                        uiOutput("filtros")
                            ))

body <- dashboardBody(tabItems(tabItem(tabName = "filtros",
                                       fluidRow(
                                         column(12,
                                                DT::dataTableOutput("tabla_julio") # %>% withSpinner(color = "#0dc5c1")
                                         )
                                       ))))

ui <-
  dashboardPagePlus(
    enable_preloader = FALSE,
    sidebar_fullCollapse = TRUE,
    header,
    sidebar,
    body
  )

server = function(input, output, session) {
  
  # Create the choices for sample input
  vals <- reactiveValues(data = iris, filtered_data = iris)
  
  output$filtros <- renderUI({
    datos <- isolate(vals$data)
    conditionalPanel(
      "input.tabs == 'filtros'",
      tagList(
        div(
          style = "display: inline-block;vertical-align:top; width: 221px;",
          numericInput(
            inputId = "SepalLength",
            label = "Sepal.Length",
            value = NA,
            min = NA,
            max = NA,
            step = NA
          )
        ),
        div(
          div(
            style = "display: inline-block;vertical-align:top; width: 224px;",
            selectInput(
              inputId = "Species",
              label = "Species",
              width = "220",
              choices = unique(isolate(datos$Species)),
              selected = NULL,
              multiple = TRUE,
              selectize = TRUE,
              size = NULL
            )
          )
        )
      ),
      actionButton("filtrar", "Filter", style = "width: 100px;"),
      actionButton("reset", "Reset", style = "width: 100px;")
    )
  })
  
  
  # Filter data
  observeEvent(input$filtrar, {
    tib <- vals$data
    
    if (!is.na(input$SepalLength)) {
      tib <- tib %>% dplyr::filter(Sepal.Length < input$SepalLength)
      print(head(tib))
    } else {
      tib
    }
    
    # Filter
    if (!is.null(input$Species)) {
      tib <- tib %>% dplyr::filter(Species %in% input$Species)
    } else {
      tib
    }
    
    print(head(tib, n = 15))
    
    vals$filtered_data <- tib
    
  })
  
  observeEvent(input$reset, {
    updateNumericInput(session, inputId = "SepalLength", value = NA)
    updateSelectInput(session, inputId = "Species", selected = "")
  })
  
  # Reactive function creating the DT output object
  output$tabla_julio <- DT::renderDataTable({
    DT::datatable(vals$filtered_data)
  }, server = FALSE)
  
}

shinyApp(ui, server)

初步回答:

我建议使用selectizeGroup模块 https://dreamrs.github.io/shinyWidgets/reference/selectizeGroup-module.html来自图书馆(闪亮小部件 https://github.com/dreamRs/shinyWidgets).

它创建了一个

相互依存的群体selectizeInput用于过滤 data.frame 的列(如 Excel 中的列)。

除此之外,它只使用selectizeInput它似乎满足您的要求,并节省了我们大量的打字时间。

这是一个使用的示例iris数据集:

library(shiny)
library(DT)
library(shinyWidgets)
library(datasets)

DF <- iris
names(DF) <- gsub("\\.", "", names(DF))

ui <- fluidPage(
  fluidRow(
    column(width = 10, offset = 1, tags$h3("Filter data with selectize group")),
    column(width = 3, offset = 1, 
           selectizeGroupUI(
             id = "my-filters",
             params = list(
               SepalLength = list(inputId = "SepalLength", title = "SepalLength:"),
               SepalWidth = list(inputId = "SepalWidth", title = "SepalWidth:"),
               PetalLength = list(inputId = "PetalLength", title = "PetalLength:"),
               PetalWidth = list(inputId = "PetalWidth", title = "PetalWidth:"),
               species = list(inputId = "Species", title = "Species:")
             ),
             inline = FALSE
           )),
    column(
      width = 10, offset = 1,DT::dataTableOutput(outputId = "table")
    )
  )
)

server <- function(input, output, session) {
  filtered_table <- callModule(
    module = selectizeGroupServer,
    id = "my-filters",
    data = DF,
    vars = names(DF),
    inline = FALSE
  )
  output$table <- DT::renderDataTable(filtered_table())
}

shinyApp(ui, server)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在闪亮的应用程序中过滤数据,但在更新表时将值保留在 selectInput 中 的相关文章

  • 需要在R中跳过不同数量的行

    我正在使用以下代码来处理我的数据 但最近我意识到使用skip 27 在数据开始之前跳过存储在我的文件中的信息 不是一个好的选择 因为每个文件中要跳过的行数不同我的目标是读取存储在多个文件夹中的各种txt文件 并非所有文件都有相同的列数 列的
  • case_when 与部分字符串匹配和 contains()

    我正在使用一个数据集 其中有许多名为 status1 status2 等的列 在这些列中 它表示某人是否豁免 完整 注册等 不幸的是 豁免投入并不一致 这是一个示例 library dplyr problem lt tibble perso
  • 使用数据帧的 R 中的 EWMA 波动性

    我正在尝试从一系列股票每日收益中获取 EWMA 波动性 这些收益来自一个名为base retorno diario Data IBOV ABEV3 AEDU3 ALLL3 BBAS3 BBDC3 BBDC4 1 2000 01 04 0 0
  • 如何将旋转的 NetCDF 转换回正常的纬度/经度网格?

    我有一个带有旋转坐标的 NetCDF 文件 我需要将其转换为正常的纬度 经度坐标 经度为 180到180 纬度为 90到90 library ncdf4 nc open dat nf 对于尺寸 它显示 1 5 variables exclu
  • R - 基于列名称的子集

    我的数据框有超过 120 列 变量 我想根据列名称创建子集 例如 我想创建一个子集 其中列名称包含字符串 心情 这可能吗 我一般用 SubData lt myData grep whatIWant colnames myData 我很清楚
  • 无法编译包“maps”

    当我安装 maps 包时 安装中出现警告 ld warning ignoring file Library Developer CommandLineTools SDKs MacOSX10 14 sdk usr lib libSystem
  • 如何将参数从 Excel/VBA 传递到 Rstudio 中的脚本

    我正在尝试使用 Rstudio 从 VBA 打开 R 脚本 同时将参数传递给 R 脚本 然后我可以使用 commandArgs 访问该脚本 该问题与此处描述的问题非常相似 WScript Shell 用于运行路径中包含空格且来自 VBA 的
  • 无法将“gather”输出的列名称更改为默认名称以外的任何名称

    我正在尝试使用gather in the tidyr包 但我无法更改默认名称的输出列名称 例如 df data frame time 1 100 a 1 100 b 101 200 df long df gt gather foo bar
  • 更改 R 中 ggplot geom_polygon 的颜色方案

    我正在使用地图库和 ggplot 的 geom polygon 创建地图 我只是想将默认的蓝色 红色 紫色配色方案更改为其他颜色 我对 ggplot 非常陌生 所以如果我没有使用正确的数据类型 请原谅 我使用的数据如下所示 gt head
  • R 数据结构的运算效率

    我想知道是否有任何关于操作效率的文档R 特别是那些与数据操作相关的 例如 我认为向数据框添加列是有效的 因为我猜您只是向链接列表添加一个元素 我想添加行会更慢 因为向量保存在数组中C level你必须分配一个新的长度数组n 1并将所有元素复
  • 在闪亮的数据表中为每个单元格显示工具提示或弹出窗口?

    有没有什么方法可以为 r闪亮数据表中的每个单元格获取工具提示 有很多方法可以获取悬停行或列 但我找不到一种方法来获取行和列索引并为每个单元格显示不同的悬停工具提示 任何人都可以修改以下代码吗 library shiny library DT
  • ggplot2:带有 geom_line 的 x 轴因子不起作用

    我想要一个线图 其中value绘制为函数expt每级一行var 这是我的数据 lines lt expt var value 1 none p 0 183065327746799 2 none p 0 254234138384241 3 n
  • 斯皮尔曼相关性和联系

    我正在一小组配对排名上计算斯皮尔曼的 rho 斯皮尔曼因处理领带不当而闻名 例如 取2组8个排名 即使两组中有6个是平局 相关性仍然很高 gt cor test c 1 2 3 4 5 6 7 8 c 0 0 0 0 0 0 7 8 met
  • 如何根据多个条件创建列?

    我有一个数据框 我想根据多个条件创建一个列 v1 v2 v3 v4 v5 4 1 2 4 5 5 5 2 4 5 6 21 9 20 30 50 6 4 5 7 9 10 3 6 5 9 基本上 使用以下可能的值创建 v6 Cat dog
  • devtools::test() 有效,但 devtools::check() 无效。为什么?

    我正在测试this https github com beanumber etlR 包 以下三件事就可以正常工作 devtools test devtools test file tests testthat R Travis CI 与 R
  • 如何使用 ggplotGrob 创建自定义图例?

    我发布了一个question https stackoverflow com questions 29174774 how to create legend text elements being different colours in
  • 使用行内 r 代码作为 R markdown 标头的一部分

    我希望使用行 R 代码作为 r markdown 文件中标头的一部分 然而 当我编织文件时 标题上使用的字体是不同的 如何确保字体相同 下面是一个简单的例子 r 1 1 Header 您可以将内容括在反引号中以表示内联 r 代码 如下所示
  • 如何使用 ggplot2 将 IPCC 点画添加到全球地图

    我需要将 IPCC style 点画添加到全球地图中 如下所示这个帖子 https stackoverflow com questions 11736996 adding stippling to image contour plot 不过
  • 函数速度测试的奇怪结果

    我编写了一个使用递归来查找最大公因数 分母 的函数 gt gcd function a b if length a length b gt 1 warning Only scalars allowed using first element
  • 根据列中的部分字符串匹配选择数据框行

    我想根据列中字符串的部分匹配从数据框中选择行 例如列 x 包含字符串 hsa 使用sqldf if它有一个like语法 我会做类似的事情 select from lt gt where x like hsa 很遗憾 sqldf不支持该语法

随机推荐