Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to stop executing of R code inside shiny (without stopping the shiny process)?

Tags:

Let's say I have a shiny app that has a function that can take a long time to run. Is it possible to have a "stop" button that tells R to stop the long-running call, without having to stop the app?

Example of what I mean:

analyze <- function() {   lapply(1:5, function(x) { cat(x); Sys.sleep(1) }) }  runApp(shinyApp(   ui = fluidPage(     actionButton("analyze", "Analyze", class = "btn-primary"),     actionButton("stop", "Stop")   ),   server = function(input, output, session) {     observeEvent(input$analyze, {       analyze()     })     observeEvent(input$stop, {       # stop the slow analyze() function     })   } )) 

edit: x-post from shiny-discuss

like image 636
DeanAttali Avatar asked Jun 02 '15 05:06

DeanAttali


People also ask

Do you need R to run Shiny app?

But the simplest way to run a Shiny app is to run it locally. You only need the shiny R package installed, and you can run the app in your browser. In this post you'll see a few ways of how to organize your files to be served locally.

Is R Shiny difficult?

Along with Shiny elements, you can use HTML elements to stylize your content in your application. In my opinion, R Shiny is very easy to learn despite how powerful the tool is. If you're working on a side project or looking to add something to your portfolio, I highly recommend trying it out.

How does R Shiny work?

Shiny comes with a reactive programming library that you will use to structure your application logic. By using this library, changing input values will naturally cause the right parts of your R code to be reexecuted, which will in turn cause any changed outputs to be updated.


1 Answers

So another answer, outside a loop : use a child process.

library(shiny) library(parallel)  # # reactive variables #  rVal <- reactiveValues() rVal$process <- NULL rVal$msg <- NULL rVal$obs <- NULL counter <- 0 results <- list() dfEmpty <- data.frame(results = numeric(0))   # # Long computation # analyze <- function() {   out <- lapply(1:5, function(x) {     Sys.sleep(1)     rnorm(1) })   data.frame(results = unlist(out)) }  # # Shiny app # shinyApp(   ui = fluidPage(     column(6,       wellPanel(         tags$label("Press start and wait 5 seconds for the process to finish"),         actionButton("start", "Start", class = "btn-primary"),         actionButton("stop", "Stop", class = "btn-danger"),         textOutput('msg'),         tableOutput('result')         )       ),     column(6,       wellPanel(         sliderInput(           "inputTest",           "Shiny is responsive during computation",           min = 10,           max = 100,           value = 40           ),         plotOutput("testPlot")         ))),   server = function(input, output, session)   {     #     # Add something to play with during waiting     #     output$testPlot <- renderPlot({       plot(rnorm(input$inputTest))     })      #     # Render messages     #     output$msg <- renderText({       rVal$msg     })      #     # Render results     #     output$result <- renderTable({       print(rVal$result)       rVal$result     })      #     # Start the process     #     observeEvent(input$start, {       if (!is.null(rVal$process))         return()       rVal$result <- dfEmpty       rVal$process <- mcparallel({         analyze()       })        rVal$msg <- sprintf("%1$s started", rVal$process$pid)      })       #     # Stop the process     #     observeEvent(input$stop, {       rVal$result <- dfEmpty       if (!is.null(rVal$process)) {         tools::pskill(rVal$process$pid)         rVal$msg <- sprintf("%1$s killed", rVal$process$pid)         rVal$process <- NULL          if (!is.null(rVal$obs)) {           rVal$obs$destroy()         }       }     })      #     # Handle process event     #     observeEvent(rVal$process, {       rVal$obs <- observe({         invalidateLater(500, session)         isolate({         result <- mccollect(rVal$process, wait = FALSE)         if (!is.null(result)) {           rVal$result <- result           rVal$obs$destroy()           rVal$process <- NULL         }       })       })     })   }   ) 

edit

See also :

  • shiny-discuss : child process
  • asynchronous-command-dispatch-in-interactive-r
like image 190
fxi Avatar answered Nov 12 '22 18:11

fxi