How can I update a subset of values in Shiny once, rather than having it update every time and undoing previous selections?

Viewed 29

I want to be able to update my table based on filtering on values within a column, based on a user-provided .csv. The code below works to get my fields populated correctly, but the filtering function is not working correctly, as it re-updates the flow and cancels out any selection I make of a value.


ui <- fluidPage(
  fileInput("data", "Load Data", accept = ".csv"),
  selectInput("column", "Column", character()),
  selectInput("level", "level", "select"),
  dataTableOutput("table")
)

server <- function(input, output, session){
  options(shiny.maxRequestSize=1000*1024^2)
  data <- reactive({
    req(input$data)
    read.csv(input$data$datapath)
  })
  
  observeEvent(data(), {
    updateSelectInput(session, "column", choices = names(data()))
  })
  
  observeEvent(input$column, {
    val <- data()[[input$column]]
    updateSelectInput(session, "level", choices = val,
                      label = paste("Choose level in", input$column))
  })
  
  output$table <- renderDataTable({
    req(input$level)
    filter(data(), input$level == input$level)
  })
}  

shinyApp(ui = ui, server = server)

I have also tried a dplyr solution for filtering,

     filter(input$value == input$value)

but that's not working either, for the same reason. I'm relatively new to Shiny, so any and all assistance and resources are appreciated.

1 Answers

Perhaps you were looking for something like this?

Using the .data pronoun. More information here.

library(shiny)
library(readr)
library(dplyr)

ui <- fluidPage(
  fileInput("data", "Load Data", accept = ".csv"),
  selectInput("column", "Column", character()),
  selectInput("level", "level", "select"),
  dataTableOutput("table")
)

server <- function(input, output, session) {
  options(shiny.maxRequestSize = 1000 * 1024^2)
  data <- reactive({
    req(input$data)
    read_csv(input$data$datapath)
  })

  observeEvent(data(), {
    updateSelectInput(session, "column", choices = names(data()))
  })

  observeEvent(input$column, {
    val <- data()[[input$column]]
    updateSelectInput(session, "level",
      choices = unique(val),
      label = paste("Choose level in", input$column)
    )
  })

  output$table <- renderDataTable({
    req(input$column)
    req(input$level)
    filter(data(), .data[[input$column]] == input$level)
  })
}

shinyApp(ui = ui, server = server)

Tested with iris.csv created with write_csv(iris, "iris.csv")

enter image description here

Related