Search code examples
rshinyshiny-server

Shiny R Action Button Controls Reactive Elements


Not sure if I should use this term. Basically, I have a reactive function which displays user uploaded CSV file and I would like to use a action button to fire a plot generation process. At this moment, the plot is always generated on the fly. So I am wondering, in the renderPlot function, how to let a action button override a reactive element. Thanks!

ui.R

library(shiny)

shinyUI(fluidPage(
  titlePanel("Test"),
  sidebarLayout(
    sidebarPanel(
      fileInput('file1', 'Choose CSV File',
                accept=c('text/csv', 
                         'text/comma-separated-values,text/plain', 
                         '.csv')),
      
      checkboxGroupInput('show_vars', 'Columns to show:',
                         choices=c("Col1"="Col1", "Col2"="Col2", "Col3"="Col3"), 
                         c("Col1"="Col1", "Col2"="Col2", "Col3"="Col3")),
      
      uiOutput("study"),
      actionButton("go", "Draw the plot")
    ),
    mainPanel(
      dataTableOutput('contents'),
      plotOutput("Plot", width = 800, height = 800)
      
    )
  )
))

server.R

shinyServer(function(input, output) {
  
  dataInput <- reactive({
    inFile <- input$file1
    if (is.null(inFile)) return(NULL)
    data_load<-subset(read.csv(inFile$datapath, header=T, sep=",", quote='"', stringsAsFactors=FALSE), select=input$show_vars)
    data_study<-unique(data_load$Col2)
    return (list("data_load"=data_load, "data_study"=data_study))
  })
 
  study <- reactive({
    all_citation<-dataInput()$data_load$Col2
    study_choose<-unlist(lapply(input$columns,  function(x) which(all_citation==x)))
    return (list("study_choose"=study_choose))
  })

  ##Generate the data table####
  output$contents <- renderDataTable({
    study_choose_temp<-study()$study_choose
    dataInput()$data_load[study_choose_temp,]
  })
  
  ###I would like the actionButton controls reactive elements 
  ###dataInput()$data_load$Col3[study()$study_choose]

  output$Plot <- renderPlot({
    input$go
    hist(dataInput()$data_load$Col3[study()$study_choose])
  })
  
  output$study <- renderUI({
    # If missing input, return to avoid error later in function
    if(is.null(dataInput()$data_study)) return()
    # Create the checkboxes and select them all by default
    checkboxGroupInput("columns", "Choose studies to plot", 
                       choices  = dataInput()$data_study,
                       selected = dataInput()$data_study)
    
  })
})

###CSV template


Solution

  • Use isolate in the renderPlot() so that it will only update when the input$go button is fired. If you do this the plot will not redraw when the other reactive elements are changed, but the input$go is outside of the isolate so it will cause the plot to redraw.

     output$Plot <- renderPlot({
        input$go
        isolate( 
            hist(dataInput()$data_load$Col3[study()$study_choose]) 
        )
      })