john
john

Reputation: 1036

Shiny Performance Improvement

I am looking for suggestions in improving performance of my shiny app. This shiny app saves data in CSV format when user selects a particular row by clicking on check box. I don't want it to save data every time when user clicks on check box. Hence I created action button so that user clicks on button only when he is done with the checkbox selection of multiple rows.

library(shiny)
library(DT)
mydata = mtcars
mydata$id = 1:nrow(mydata)

runApp(
  list(ui = pageWithSidebar(
    headerPanel('Examples of Table'),
    sidebarPanel(
      textInput("collection_txt",label="RowIndex")
      ,br(),
      actionButton("run", "Write Data"),
      br(),
      p("Writeback with every user input. CSV file gets saved on your working directory!")),

    mainPanel(
      DT::dataTableOutput("mytable")
    ))

    , server = function(input, output, session) {

      shinyInput <- function(FUN,id,num,...) {
      inputs <- character(num)
      for (i in seq_len(num)) {
        inputs[i] <- as.character(FUN(paste0(id,i),label=NULL,...))
      }
      inputs
    }

    rowSelect <- reactive({

      rows=names(input)[grepl(pattern = "srows_",names(input))]
      paste(unlist(lapply(rows,function(i){
        if(input[[i]]==T){
          return(substr(i,gregexpr(pattern = "_",i)[[1]]+1,nchar(i)))
        }
      })))

    })

    observe({
      updateTextInput(session, "collection_txt", value = rowSelect() ,label = "RowIndex:" )
      d = data.frame(n = rowSelect(), stringsAsFactors = F)
       if (input$run == 0)
         return()
      isolate({write.csv(mydata[as.numeric(d$n),], file = "Writeback.csv" , row.names=F)})
    })


    output$mytable = DT::renderDataTable({
    DT::datatable(cbind(Flag=shinyInput(checkboxInput,"srows_",nrow(mydata),value=NULL,width=1), 
                    mydata),   extensions = 'Buttons', options = list(orderClasses = TRUE,
                                   pageLength = 5, lengthChange = FALSE, dom = 'Bfrtip',
                                   buttons = c('copy', 'csv', 'excel'),
                                   drawCallback= JS(
                                     'function(settings) {
                                     Shiny.bindAll(this.api().table().node());}')
                                  ),escape=F)

      }
  )

    }), launch.browser = T
)

I want action button to write data in CSV format only when user clicks on action button. Is there any way to improve the code below.

  d = data.frame(n = rowSelect(), stringsAsFactors = F)
   if (input$run == 0)
     return()
  isolate({write.csv(mydata[as.numeric(d$n),], file = "Writeback.csv" , row.names=F)})

Upvotes: 0

Views: 228

Answers (2)

SeGa
SeGa

Reputation: 9809

Why are you not using observeEvent for the actionButton?

observeEvent(input$run, {
  updateTextInput(session, "collection_txt", value = rowSelect() ,label = "RowIndex:" )
  d = data.frame(n = rowSelect(), stringsAsFactors = F)
  write.csv(mydata[as.numeric(d$n),], file = "Writeback.csv" , row.names=F)
})

Upvotes: 1

W148SMH
W148SMH

Reputation: 172

I think you're looking for the require function req(input$run) or try if(is.null(input$run)==T){return()}

Upvotes: 0

Related Questions