简体   繁体   English

如何创建Shiny R动态renderTable,并使用上载CSV文件确定的表数量?

[英]How to create Shiny R dynamic renderTable, with a number of tables determined by the uploaded CSV files?

I am building web app that after uploading csv files transforms the data and then should be able to output few tables. 我正在构建网络应用程序,该应用程序在上传csv文件后会转换数据,然后应该能够输出一些表格。 The number of the tables depends strictly on the information included in the csv files, therefore is calculated during the data transformation process. 表的数量严格取决于csv文件中包含的信息,因此是在数据转换过程中计算的。 I have created a list lst with data frames that have to be outputted. 我创建了一个列表lst ,其中包含必须输出的数据帧。 The length of the list is the number of the tables that should be created. 列表的长度是应创建的表的数量。 After searching the web I encountered very similar question ( here ), which is unfortunately not answered yet. 在网上搜索后,我遇到了非常相似的问题( 在此处 ),很遗憾,尚未回答。 Does anyone has an idea how to solve it? 有人知道如何解决吗?

Some of my code (not all, due to significant data transformation), where I would like to replace fixed max_table with variable length(data_set()) : 我的一些代码(不是全部,由于大量的数据转换),在这里我想用可变的length(data_set())代替固定的max_table

library(shiny)

ui <- fluidPage(
  fluidRow(column(3,
                  wellPanel(
                    fileInput(inputId = "files",
                              label = "Choose cvs files",
                              accept=c('text/csv', 
                                       'text/comma-separated-values,text/plain', 
                                       '.csv'),
                              multiple = TRUE))),
           column(5, offset = 1, 
                  uiOutput("tables")
                  )
           )
  )

max_table <- 5
server <- function(input,output){


  data_set <- reactive({
    if(is.null(input$files)){
      return(NULL)
    }

    lst <- list()
    for(i in 1:length(input$files[,1])){
      lst[[i]] <- read.csv(input$files[[i, 'datapath']], sep = ",", header = TRUE, skip = 4, dec = ".")
    }
    lst
  })

  output$tables <- renderUI({
    plot_output_list <- lapply(1:max_table, function(i) {
      tablename <- paste("tablename", i, sep="")
      tableOutput(tablename)
    })
    do.call(tagList, plot_output_list)
  })


  for (i in 1:max_table){
    local({
      my_i <- i
      tablename <- paste("tablename", my_i, sep="")
      output[[tablename]] <- renderTable({data_set()[[my_i]] 
      })
    })    
  }
}

shinyApp(ui = ui, server = server)

Any help would be much appreciated! 任何帮助将非常感激!

A solution is to put everything inside an observe . 一种解决方案是将所有内容放入observe

library(shiny)

ui <- fluidPage(
  fluidRow(column(3,
                  wellPanel(
                    fileInput(
                      inputId = "files",
                      label = "Choose cvs files",
                      accept = c('text/csv',
                                 'text/comma-separated-values,text/plain',
                                 '.csv'),
                      multiple = TRUE
                    )
                  )),
           column(5, offset = 1, uiOutput("tables"))))

server <- function(input, output) {
  observe({
    if (!is.null(input$files)) {
      max_table = length(input$files[, 1])

      lst <- list()
      for (i in 1:length(input$files[, 1])) {
        lst[[i]] <-
          read.csv(
            input$files[[i, 'datapath']],
            sep = ",",
            header = TRUE,
            skip = 4,
            dec = "."
          )
      }

      output$tables <- renderUI({
        plot_output_list <- lapply(1:max_table, function(i) {
          tablename <- paste("tablename", i, sep = "")
          tableOutput(tablename)
        })
        do.call(tagList, plot_output_list)
      })

      for (i in 1:max_table) {
        local({
          my_i <- i
          tablename <- paste("tablename", my_i, sep = "")
          output[[tablename]] <- renderTable({
            lst[[my_i]]
          })
        })
      }
    }
  })

}

shinyApp(ui = ui, server = server)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM