如何在同一个App中上传数据(作为一个reactive object在多处处理)和下载数据?

How to upload data (as a reactive object for processing in multiple places) and download data in the same App?

请参阅最底部的最终工作 MWE 代码,其中包含 gss 提出的建议!

在 运行 下面的 MWE 代码中,如果用户单击侧边栏面板顶部的“浏览”按钮并访问 csv 文件,则该文件中的数据将上传并显示为table 在主面板中。但是,我还希望将 csv 数据作为矩阵或向量反映在该侧边栏面板中呈现的矩阵中。如底部图像所示。关于如何做到这一点有什么想法吗?

在下面的 MWE 代码中,您可以看到我的注释 observeEvent() 由“浏览”触发,我尝试这样做,包括使用 shinyMatrix 包的 updateMatrixInput() 函数。没用。

最终我计划取消 table 渲染,因为没有必要两次查看相同的数据。但现在为了测试,我正在尝试 运行 它们并行。

library(shiny)
library(shinyMatrix)

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      fileInput("file1", "Optionally choose input file (csv)", accept = ".csv"),
      matrixInput("matrix1", 
                  value = matrix(c(5), ncol = 1, dimnames = list("Matrix 1 input",NULL)),
                  cols =  list(names = FALSE),
                  class = "numeric"),
      downloadButton("download")
    ),
    mainPanel(
      tableOutput("contents"),
    )
  )
)

server <- function(input, output, session) {
  
  output$contents <- renderTable({
    file <- input$file1
    ext <- tools::file_ext(file$datapath)
    req(file)
    validate(need(ext == "csv", "Please upload a csv file"))
    data <- read.csv(file$datapath, header = TRUE)
    data
  })
  
  # observeEvent(input$file1,{
  #   tmpMat <- matrix(c(data), ncol=1)
  #   updateMatrixInput(session, inputId = "matrix1", value = tmpMat)
  # })
  
  output$download <- downloadHandler(
    filename = function() {
      paste("Inputs","csv",sep=".")
    },
    content = function(file) {
      write.csv(input$matrix1[1,1], file,row.names=FALSE)
    }
  )
 
}

shinyApp(ui, server)

基于 gss 解决方案的最终工作 MWE 代码:

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      fileInput("file1", "Optionally choose input file (csv)", accept = ".csv"),
      matrixInput("matrix1", 
                  value = matrix(c(5), 
                          ncol = 1, 
                          dimnames = list("Matrix 1 input",NULL)
                  ),
                  cols =  list(names = FALSE),
                  class = "numeric"
      ),
      downloadButton("download")
    ),
    mainPanel(
      tableOutput("contents"),
    )
  )
)

server <- function(input, output, session) {
  
  input_file <- reactive({
    file <- input$file1
    ext <- tools::file_ext(file$datapath)
    req(file)
    validate(need(ext == "csv", "Please upload a csv file"))
    read.csv(file$datapath, header = TRUE)
  })
  
  output$contents <- renderTable({
    input_file()
  })
  
  observeEvent(input$file1,{
    updateMatrixInput(session, 
                      inputId = "matrix1", 
                      value = matrix(as.matrix(input_file()),
                                     ncol=1,
                                     dimnames = list("Matrix 1 input",NULL)
                              )
    )
                      
  })
  
  output$download <- downloadHandler(
    filename = function() {
      paste("Inputs","csv",sep=".")
    },
    content = function(file) {
      write.csv(input$matrix1[1,1], file,row.names=FALSE)
    }
  )
}

shinyApp(ui, server)

你需要改变这个:

output$contents <- renderTable({
    file <- input$file1
    ext <- tools::file_ext(file$datapath)
    req(file)
    validate(need(ext == "csv", "Please upload a csv file"))
    data <- read.csv(file$datapath, header = TRUE)
    data
  })

你需要的是有一个反应式,以后可以在不同的地方使用,所以只需:

input_file <- reactive({
    file <- input$file1
    ext <- tools::file_ext(file$datapath)
    req(file)
    validate(need(ext == "csv", "Please upload a csv file"))
    data <- read.csv(file$datapath, header = TRUE)
    data
})

output$contents <- renderTable({
    input_file()
  })

您现在也可以在其他地方使用 input_file()