You could use renderUI to build the UI from the server. Then you could simply use one of the columns from the dataframe you have in the server to build your select input?
See here for how to use renderUI.
ui <- fluidPage(
uiOutput("sidebarOutput"),
uiOutput("mainPanel")
)
server <- function(input,output){
df <- data.frame('col1' = c(1,2,3), 'col2' = c(1,2,3))
output$sidebarOutput <- renderUI({
sidebarPanel(
selectInput(inputId = 'col1Input',
label =colnames(df[1]),
choices = df[[1]]))
})
output$mainPanel <- renderUI({
output$table <- DT::renderDataTable({
validate(
need(input$col1Input != "", "No column selected")
)
dplyr::filter(df, col1 == input$col1Input)
})
mainPanel(
DT::dataTableOutput("table")
)
})
}
shinyApp(ui = ui, server = server)
Edit:
You might also want to filter on a specific column that you select. You can do this like so:
ui <- fluidPage(
uiOutput("sidebarOutput"),
uiOutput("mainPanel")
)
server <- function(input,output){
df <- data.frame('col1' = c(1,2,3), 'col2' = c(4,5,6))
output$sidebarOutput <- renderUI({
sidebarPanel(
selectInput(inputId = 'filtercolumn',
label = "Select a column to filter on",
choices = colnames(df)),
renderUI({selectInput(inputId = 'valuetofilter',
label = paste0("filtering on column: ", colnames(df[input$filtercolumn])),
choices = df[[input$filtercolumn]])})
)
})
output$mainPanel <- renderUI({
output$table <- DT::renderDataTable({
validate({
need(input$filtercolumn != "", "No column selected")
need(input$valuetofilter != "", "No value selected")
})
dplyr::filter(df,(!!as.name(input$filtercolumn)) == !!input$valuetofilter) #note the unquoting
})
mainPanel(
DT::dataTableOutput("table")
)
})
}
shinyApp(ui = ui, server = server)
With thanks to this answer