简体   繁体   中英

Subset a dataframe based on dynamic number and names of columns

I have the shiny app below in which the user may select between one or more column names from the data frame.

name<-c("John","Jack","Bill")
value1<-c(2,4,6)
add<-c("SDF","GHK","FGH")
value2<-c(3,4,5)
dt<-data.frame(name,value1,add,value2)

Then for every selection he makes the relative pickerInput() may be displayed below. Then based on the selection of column or columns and their values I would like to subset the initial dataframe and display it in a table. But the name of the columns may differ for every different dataframe Im going to use in my original app so I do not know hot to subset it.

library(DT)
# ui object
ui <- fluidPage(
    titlePanel(p("Spatial app", style = "color:#3474A7")),
    sidebarLayout(
        sidebarPanel(
            pickerInput(
                inputId = "p1",
                label = "Select Column headers",
                choices = colnames( dt),
                multiple = TRUE,
                options = list(`actions-box` = TRUE)
            ),
            #Add the output for new pickers
            uiOutput("pickers")
        ),
        
        mainPanel(
            DTOutput("table")
        )
    )
)

# server()
server <- function(input, output) {
    
    observeEvent(input$p1, {
        #Create the new pickers 
        output$pickers<-renderUI({
            div(lapply(input$p1, function(x){
                if (is.numeric(dt[[x]])) {
                    sliderInput(inputId=x, label=x, min=min(dt[x]), max=max(dt[[x]]), value=c(min(dt[[x]]),max(dt[[x]])))
                }
                else if (is.factor(dt[[x]])) {
                    selectInput(
                        inputId = x#The colname of selected column
                        ,
                        label = x #The colname of selected column
                        ,
                        choices = dt[,x]#all rows of selected column
                        ,
                        multiple = TRUE
                        
                    )
                }
                
            }))
        })
    })
    output$table<-renderDT({
        req(input$p1, sapply(input$p1, function(x) input[[x]]))
        dt_part <- dt
        for (colname in input$p1) {
            dt_part <- subset(dt_part, dt_part[[colname]] %in% input[[colname]])
        }
        dt_part
    })
}

# shinyApp()
shinyApp(ui = ui, server = server)

If you change your output$table to the following, it works:

output$table<-renderDT({
  req(input$p1, sapply(input$p1, function(x) input[[x]]))
  dt_part <- dt
  for (colname in input$p1) {
      if (is.factor(dt_part[[colname]])) {
        dt_part <- subset(dt_part, dt_part[[colname]] %in% input[[colname]])
      } else {
        dt_part <- subset(dt_part, (dt_part[[colname]] >= input[[colname]][[1]]) & dt_part[[colname]] <= input[[colname]][[2]])
      }
  }
  dt_part
})

The first line makes sure the required fields are available.
The rest of the lines repeatedly filter dt based on the columns in input$p1 and values in input[[input$p1]] .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM