Returning multiple data frames with shiny::stopApp

I want to use Shiny within RMarkdown for users to upload data (xlsx file).
Then I want to pass all the worksheets as R data frames (w/o reactivity) to run rest of the RMarkdown file.
I mainly want to convert them into data frames so I can use reticulate to run Python code as well.

I've tried this, and it doesn't seem to quite work:


library(dplyr)
library(miniUI)
library(shiny)
library(XLConnect)

launch_shiny <- function() {
  
  ui <- miniPage(
    gadgetTitleBar("Input Data"),
    miniContentPanel(
      fileInput(inputId = "my.file", label = NULL, multiple = FALSE)
    )
  )
  
  server <- function(input, output, session) {
    wb <- reactive({
      new.file <- input$my.file
      loadWorkbook(
        filename = new.file$datapath,
        create = FALSE,
        password = NULL
      )
    })
    
    observeEvent(input$done, {
      stopApp(c(wb()))
    })
    
  }
  runGadget(ui, server)
  
}

test <- launch_shiny()
df1 <- readWorksheet(object = test, sheet = "sheet1")
df2 <- readWorksheet(object = test, sheet = "sheet2")

It throws this error:

Error in (function (classes, fdef, mtable)  : 
  unable to find an inherited method for function ‘readWorksheet’ for signature ‘"list", "character"’

I can return one sheet at a time using stopApp(readWorksheet(object = wb(), sheet = "sheet1")), but I can't seem to return an entire workbook or multiple data frames at the same time.

I don't really want to read in xlsx, save each sheet as csv in working directory, then read those files in again.
Would anyone have a good suggestion on how to get around this?

In the stopApp part, you wrap the wb value in a vector with c(). c creates a list when any of its arguments aren't atomic vectors. From the documentation (?c):

The output type is determined from the highest type of the components in the hierarchy NULL < raw < logical < integer < double < complex < character < list < expression. Pairlists are treated as lists, whereas non-vector components (such names and calls) are treated as one-element lists which cannot be unlisted even if recursive = TRUE.

Try changing your code to this:

observeEvent(input$done, {
  stopApp(wb())
})
1 Like

The file path is no longer valid after app is stopped. I was able to return a list of data frames though. Thanks for your input!

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.