将反应性数据传递到全球环境

时间:2019-04-24 05:51:28

标签: r shiny r-markdown

我想在RMarkdown中使用Shiny,以便用户上传数据(xlsx文件)。
 然后,我想将所有工作表作为R数据帧(不带反应性)传递,以运行其余的RMarkdown文件。
我主要想将它们转换为数据帧,以便可以使用reticulate来运行Python代码。

我已经尝试过了,但似乎不太可行:


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")

它抛出此错误:

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

我可以使用stopApp(readWorksheet(object = wb(), sheet = "sheet1"))一次返回一张纸,但似乎无法一次返回整个工作簿或多个数据帧。

我真的不想读xlsx,将每张工作表另存为csv,然后再读入这些文件。
有人会对如何解决这个问题有很好的建议吗?

1 个答案:

答案 0 :(得分:1)

fileInput()的文档中详细说明:

  

数据路径

     

包含以下数据的临时文件的路径   已上传。如果用户执行其他上载,则该文件可能会被删除   操作。

这意味着输入变量中的datapath是一个临时文件,在您关闭应用程序后将无法再访问该文件,这就是功能readWorksheet会尝试执行的操作。

因此,您必须阅读服务器中的工作表并以某种方式返回数据帧。 我通过定义第二个反应性值来做到这一点,该值基本上是在lapply的所有工作表上应用wb返回的数据帧的列表,在这种情况下,test将是此数据帧的列表

可能有其他方法(更有效,或更适合您的目的)来做到这一点,但这是:

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
      )
    })

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    df_lst <- reactive({
      # read all sheets into a list
      lapply(getSheets(wb()), 
             function(sheet){
               readWorksheet(object = wb(), 
                             sheet = sheet)
             })
    })
   # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    observeEvent(input$done, {
      # get the list of dfs from the app
      stopApp(c(df_lst())) 
    })

  }
  runGadget(ui, server)
  }

test <- launch_shiny()