通过checkboxGroupInput过滤数据帧行

时间:2017-11-07 11:03:44

标签: r shiny

这是一个闪亮的应用程序,其输出是data.frame iris。可以通过复选框过滤行。我认为我的代码有点乱,而且很复杂 有没有人知道如何保持简单,愚蠢?

library(shiny)

# ui ###########################################################################
ui <- fluidPage(
  checkboxGroupInput("filterSpecies", "filterSpecies",
                     selected = c("setosa", "Sepal.WidthBiggerThen3"),
                     c("setosa", "Sepal.WidthBiggerThen3")
  ),
  tableOutput("table")
)


# global #######################################################################
load(iris)

filter <- function(dt, vars){
  # only if there is min 1 no NA element
  if(any(!is.na(vars))){
    vars <- unlist(strsplit(vars, "\\s+"))
  }

  # value of checkbox
  var1exist <- "setosa" %in% vars
  var2exist <- "Sepal.WidthBiggerThen3" %in% vars

  cond1 <- dt$Species == "setosa"
  cond2 <- dt$Sepal.Width > 3

  # negate if the checkbox is false
  if(var1exist){
    cond1 <- T
  }else{
    cond1 <- !cond1
  }

  if(var2exist){
    cond2 <- T
  }else{
    cond2 <- !cond2
  }

  condition <- cond1 & cond2
  dt[condition, ]
}


# server #######################################################################
server <- function(input, output){

  values <- reactiveValues(x = iris)

  output$table <- renderTable({(values$x)})

  # filtering
  observe({
    values$x <- filter(iris, input$filterSpecies)
  })
}


shinyApp(ui, server)

1 个答案:

答案 0 :(得分:1)

你使它变得更复杂,而不是使用reactValues并观察尝试使用反应函数。

如果您在if语句的两种情况下都将值赋值,请尝试将if语句放入asignment中

library(shiny)

# ui ###########################################################################
ui <- fluidPage(
  checkboxGroupInput("filterSpecies", "filterSpecies",
                     selected = c("setosa", "Sepal.WidthBiggerThen3"),
                     c("setosa", "Sepal.WidthBiggerThen3")
  ),
  tableOutput("table")
)


# global #######################################################################
load(iris)



# server #######################################################################
server <- function(input, output){
  filter <- reactive({
    # only if there is min 1 no NA element
    dt = values()
    vars = input$filterSpecies



    # negate if the checkbox is false
    cond1 <- if("setosa" %in% vars){
      dt$Species == "setosa"
    }else{
      dt$Species != "setosa"
    }

    cond2 <- if("Sepal.WidthBiggerThen3" %in% vars){
      dt$Sepal.Width > 3
    }else{
      dt$Sepal.Width <= 3
    }
    condition <- cond1 & cond2
    dt[condition, ]
  })

  values <- reactive({iris})

  output$table <- renderTable({filter()})

  # filtering

}


shinyApp(ui, server)