在闪亮的 R 中使用 selectInput 来选择和过滤行,而不是选择列

Posted

技术标签:

【中文标题】在闪亮的 R 中使用 selectInput 来选择和过滤行,而不是选择列【英文标题】:Using selectInput in shiny R to select and filter rows, not select columns 【发布时间】:2018-10-25 05:26:15 【问题描述】:

我正在尝试使用闪亮的 selectInput 函数从数据框中过滤行,例如“mtcars”。因此,用户将选择他想要查看的汽车,并且 outputTable 将仅显示所选汽车的统计信息。在 selectInput 示例中,选择作用于列:

## Only run examples in interactive R sessions
if (interactive()) 

# basic example
shinyApp(
  ui = fluidPage(
    selectInput("variable", "Variable:",
                c("Cylinders" = "cyl",
                  "Transmission" = "am",
                  "Gears" = "gear")),
    tableOutput("data")
  ),
  server = function(input, output) 
    output$data <- renderTable(
      mtcars[, c("mpg", input$variable), drop = FALSE]
    , rownames = TRUE)
  
)

但是,我正在尝试使用 dplyr 根据用户输入选择的汽车来过滤掉汽车:

library(shiny)
library(dplyr)

#####Just adding a column name to mtcars for the cars column####
#cars <- mtcars
#mtcars <-setNames(cbind(rownames(cars), cars, row.names = NULL), 
#                  c("cars", "mpg", "cyl", "disp", "hp", "drat", "wt", "qsec", "vs", "am", "gear", "carb"))

if (interactive()) 

  shinyApp(
    ui = fluidPage(
      selectInput("variable", "Pick a Car: ",
                  c("All" = "All Cars",
                    "Ford" = "Ford",
                    "Volvo" = "Volvo",
                    "Ferrari" = "Ferrari",
                    "Fiat" = "Fiat",
                    "Merc" = "Merc")),
      tableOutput("data")
    ),


    server = function(input, output) 

      output$cars <- renderText(
        mtcars %>%
          filter(mtcars$cars %in% as.character(input$variable))
      )

      output$data <- renderTable(
        output$cars
      )

    
  )

任何建议将不胜感激!

【问题讨论】:

【参考方案1】:

首先,第二个示例中的 input$variable 不为人所知,因为您的 selectInput-ID 是“汽车”。然后你不使用 renderText 输出,所以过滤永远不会发生。最后,mtcars 数据中没有可能的选择。所以无论如何,它永远不会为表找到任何数据。

我编写了一个可重现的示例,将可选选项更改为 mtcars 数据的实际名称。

rm(list=ls())
cars <- mtcars
mtcars <-setNames(cbind(rownames(cars), cars, row.names = NULL),
                 c("cars", "mpg", "cyl", "disp", "hp", "drat", "wt", "qsec", "vs", "am", "gear", "carb"))
library(shiny)
library(DT)
if (interactive()) 

  shinyApp(
    ui = fluidPage(
      selectInput(inputId = "variable", label = "Pick a Car: ",choices = 
                    c("Mazda RX4 Wag" = "Mazda RX4 Wag",
                    "Merc 280" = "Merc 280",
                    "Volvo 142E" = "Volvo 142E",
                    "Duster 360" = "Duster 360",
                    "Lotus Europa" = "Lotus Europa"), selected = "Mazda RX4 Wag"),
      verbatimTextOutput("cars"),
      tableOutput("data")
    ),


    server = function(input, output) 

      carReact <- reactiveValues(car=NULL)

      output$cars <- renderText(
        txt <- mtcars[mtcars$cars %in% as.character(input$variable),]
        ## Use regex() or match() for example, if you only want partial matching of the car names.

        carReact$car <- txt
        paste(txt, collapse = ";")
      )

      output$data <- renderTable(
        req(carReact$car)
        datatbl <- carReact$car
        as.data.frame(datatbl)
      )

    
  )

选定的汽车名称保存在 reactiveValue (carReact) 中,并在 renderText 函数中分配。并且 renderText 不能打印出列表,所以你必须把它只给 1 个变量或者使用 paste() 函数。

【讨论】:

【参考方案2】:

您只需要renderTable() 并将过滤后的数据帧传递给它。 要过滤数据框,我们需要找到行名中存在input$cars 的那些行(或添加的列car)。 但这在选择All时不起作用,这就是我们使用条件input$cars == 'All Cars'的原因。

这应该可行:

shinyApp(
  ui = fluidPage(
    selectInput("cars", "Pick a Car: ",
                c("All" = "All Cars",
                  "Ford" = "Ford",
                  "Volvo" = "Volvo",
                  "Ferrari" = "Ferrari",
                  "Fiat" = "Fiat",
                  "Merc" = "Merc")),
    tableOutput("data")
  ),


  server = function(input, output) 

    mtcars$car <- rownames(mtcars)

    output$data <- renderTable(
      mtcars %>%
        filter(stringr::str_detect(car, as.character(input$cars)) | input$cars == 'All Cars')
    )

  
)

【讨论】:

如果你将 stringr::str_detect(car..) 改为 stringr::str_detect(cars..) 就可以了。 @GGamba 如果我想使用这种技术来消除传单地图而不是表格上的标记怎么办? 虽然基本概念相同,但对传单对象进行操作可能是一项截然不同的任务,值得自己提出问题 似乎已经弄清楚了,但如果没有您的帮助,这将是不可能的。谢谢!

以上是关于在闪亮的 R 中使用 selectInput 来选择和过滤行,而不是选择列的主要内容,如果未能解决你的问题,请参考以下文章

来自 selectInput 的具有多个条件的闪亮 R 观察事件

并非所有给定的 selectInput 选项都以闪亮的 R 显示

R闪亮:当multiple = TRUE时selectInput()不反映变量选择

如何将我的 selectInput 链接到我的 DataTable 以根据选择更新表? (这是R闪亮)

R - 当用户在不同的页面上时,闪亮的数据表(renderDataTable)重新加载到第一页并更新某个列值(selectInput)

错误:所有观察都在同一组中,同时从闪亮的ui列表中动态过滤R模型