代码之家  ›  专栏  ›  技术社区  ›  Ferroao

按多列中的值在r shining中高效筛选数据帧

  •  0
  • Ferroao  · 技术社区  · 6 年前

    我想知道一种有效的方法来完成以下工作。有反应性的 dataframe() 在闪亮的应用程序中。我想要两个无功输入(每个都有两个可能性 TRUE FALSE ,分别基于两列中的值对行进行子集。如果我只有一个输入(和一列 photos )我会做如下的事情:

    df<-reactive({
      df<-mydf
      if(input$myinput==FALSE)
      {
        df<-df[!df$photos=="",]
      }
      else{
        df
      }
    }) 
    

    问题是如果我有两个(或更多)输入(和列),如果我使用嵌套的,代码将增长太多。 if else 里面 如果 其他的 在上面的例子中,考虑到两个 TRUE/FALSE 输入。

    编辑:可复制,使第二个输入工作不太多 如果 其他的 :

    server <- function(input, output, session) { 
      df<-reactive({
        df<-iris
        if(input$Petalw==T)
        {
          df<-df[df$Petal.Width==0.2,]
        }
        else{
          df
        }
      }) 
      output$table <- DT::renderDataTable(
        DT::datatable(df(), options = list(searching = FALSE,pageLength = 25))
      )
    }
    ui <- navbarPage(
      title = 'Select values in two columns based on two inputs respectively',
      fluidRow(
        column(width = 3,
               checkboxInput("Petalw","PetalWithIs0.2",T),
               checkboxInput("PetalL","PetalLengthis1.4",T)
        ),
        column(9,
      tabPanel('Table',       DT::dataTableOutput('table'))
      )
      )
    )
    shinyApp(ui, server) 
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   Tonio Liebrand    6 年前

    您可以通过 input[[inputName]] 其中input name是输入的名称(例如“sepal.length-7.9”)。 然后您可以通过

    if(input[[inputName]]){
       split <- strsplit(inputName, "-")[[1]]
       name <- split[1]
       treshold <- as.numeric(split[2])
       global$filter[, inputName ==colnames(filter)] <- iris[name] == treshold
    }else{
       global$filter[, inputName ==colnames(filter)] = TRUE
    }
    

    可以创建的输入 renderUI() :

    output$checkBoxes <- renderUI({
        lapply(inputNames, function(inputName) checkboxInput(inputName, inputName, FALSE))
      })
    

    在这个例子中,我使用了所有数值列的最大值。

    完整代码为:

    restr <- apply(iris, 2, max)[1:4]
    inputNames <- paste(names(restr), restr, sep = "-") 
    filter = sapply(inputNames, function(inputName) c(inputName = return(rep(TRUE, dim(iris)[1]))))
    
    
    server <- function(input, output, session) { 
      global <- reactiveValues(filter = filter)
    
      df <- reactive({
          for(inputName in inputNames){
            if(!is.null(input[[inputName]])){
              isolate({
                if(input[[inputName]]){
                  split <- strsplit(inputName, "-")[[1]]
                  name <- split[1]
                  treshold <- as.numeric(split[2])
                  global$filter[, inputName ==colnames(filter)] <- iris[name] == treshold
                }else{
                  global$filter[, inputName ==colnames(filter)] = TRUE
                }
              })
            }
          }
          iris[rowSums(global$filter) == 4, ]
        })
    
    
      output$checkBoxes <- renderUI({
        lapply(inputNames, function(inputName) checkboxInput(inputName, inputName, FALSE))
      })
    
      output$table <- DT::renderDataTable(
        DT::datatable(df(), options = list(searching = FALSE,pageLength = 25))
      )
    }
    ui <- navbarPage(
      title = 'Select values in two columns based on two inputs respectively',
      fluidRow(
        column(width = 3,
               uiOutput("checkBoxes")
        ),
        column(9,
               tabPanel('Table', DT::dataTableOutput('table'))
        )
      )
    )
    shinyApp(ui, server) 
    
        2
  •  0
  •   Vishesh Shrivastav Akitha_MJ    6 年前

    您可以让用户为一列选择一个值,根据该值对数据进行子集,然后使用 renderUI 并产生动态 selectInput 包含其他列中的值的下拉列表。

    server <- function(input, output, session) { 
      df <- reactive({
        subset(iris, Petal.Width == input$Petalw)
      })
    
      # Extract list of Petal Lengths from selected data - to be used as a filter
      p.lengths <- reactive({
        unique(df()$Petal.Length)
      })
    
      # Filter based on Petal Length
      output$PetalL <- renderUI({
        selectInput("PetalLengthSelector", "PetalLength", as.list(p.lengths()))
      })
    
      # Subset this data based on the values selected by user
      df_1 <- reactive({
        foo <- subset(df(), Petal.Length == input$PetalLengthSelector)
        return(foo)
      })
    
      output$table <- DT::renderDataTable(
        DT::datatable(df_1(), options = list(searching = FALSE,pageLength = 25))
      )
    }
    ui <- navbarPage(
      title = 'Select values in two columns based on two inputs respectively',
      fluidRow(
        column(width = 3,
               selectInput("Petalw","PetalWidth", choices = unique(iris$Petal.Width)),
               uiOutput("PetalL")
        ),
        column(9,
               tabPanel('Table', DT::dataTableOutput('table'))
        )
      )
    )
    shinyApp(ui, server)