使用类似于函数的 R shiny 模块输出

Using R shiny module outputs similar to functions

我正在尝试使用以下代码实现以下目标:

  1. Import.Excel.Data.UI 和 Import.Excel.Data.Server 构成模块的 UI 和服务器块,这将帮助我输入“a) Excel 文件路径,b) Sheet 名称,c) 数据范围和 d) 复选框输入”。这个想法是将数据框作为输出,每行包含上述 4 列。
  2. Import.Excel.Data.App 是我尝试使用上述模块输出的地方。这个想法是使用模块中生成的数据帧并将每一行分别传递给 readXLS 函数。在代码中,我通过
  3. 行分配此输出
ABC <- Import.Excel.Data.Server("File1")
  1. 我的问题:我以为我在上面的模块 1 中生成了一个数据框。但是,当我尝试提取 class 时,结果是 class 字符而不是 class data.frame。我正在尝试通过代码
  2. 打印 class
   output$ABC.class <- renderText(class(ABC()))
   output$ABC.matrix <- renderPrint(ABC())

在 Import.Excel.Data.App

的服务器部分

我无法找出错误 - 虽然我不确定我分配它的方式(如上面 2 所示)是否正确。

如有任何帮助,我们将不胜感激。
完整代码如下

模块代码

library(shiny)

Import.Excel.Data.UI <- function(id){
  
   ns <- NS(id)
  
  tagList(
    actionButton(ns("AddExcelDataButton"), label = "Click Here to Add Excel Data"),
    verbatimTextOutput(ns("XLmatrix"))
  )
  
}




Import.Excel.Data.Server <- function(id){
  moduleServer(id, function(input, output, session){
    ns <- session$ns
    observeEvent(eventExpr = input$AddExcelDataButton,
                
                 insertUI(selector=paste0("#",ns("AddExcelDataButton")),
                          multiple=TRUE,
                          where = "afterEnd",
                          
                          ui = tags$hr(
                            tags$div(fileInput(inputId = ns(paste0("ExcelFile",input$AddExcelDataButton)),
                                         label = paste0("Path for File",input$AddExcelDataButton),
                                         multiple  = FALSE),
                                     style = "display:inline-block; vertical-align:top"
                                     ),#end of tags$div
                          
                             tags$div(textInput(inputId = ns(paste0("ExcelSheetName",input$AddExcelDataButton)),
                                      label = paste0("Excel Sheet Name",input$AddExcelDataButton),
                                      value = "Data"),
                                      style = "display:inline-block; vertical-align:top"
                                      ),#end of tags$div
                            
                            tags$div(textInput(inputId = ns(paste0("ExcelSheetRange",input$AddExcelDataButton)),
                                               label = paste0("Excel Sheet Range", input$AddExcelDataButton),
                                               value = "C6:AL10000"),
                                     style = "display:inline-block; vertical-align:top"
                            ),#end of tags$div
                            
                            
                            tags$div(checkboxInput(inputId = ns(paste0("ExcelFileCheck",input$AddExcelDataButton)),
                                               label = paste0("Check to Use File", input$AddExcelDataButton),
                                               value = TRUE),
                                     style = "display:inline-block; vertical-align:center"
                            )#end of tags$div
                 
                 
                 )#end of tags$hr  
                 
                 )#end of insertUI
    )#end of observeEvent
    
   
    
    XLdata <- reactive({
      for (i in 1: input$AddExcelDataButton)
      {
       temp.filepath <- input[[paste0("ExcelFile",i)]]$datapath
       temp.sheetname <- input[[paste0("ExcelSheetName",i)]]
       temp.sheetrange <- input[[paste0("ExcelSheetRange",i)]]
       temp.filecheck <- input[[paste0("ExcelFileCheck",i)]]
       row.temp <- cbind(temp.filepath, temp.sheetname, temp.sheetrange, temp.filecheck)
        
        
        
        ifelse(i<=1,
              {
                XLdata.matrix <- row.temp
              },#end of if condition in ifelse i<=1
              {
                XLdata.matrix <- rbind(XLdata.matrix, row.temp)
              } #end of else in ifelse i<=1
              )#end of ifelse brackets
        
      }#end of for-loop
      
   
      XLdata.matrix <- as.data.frame(XLdata.matrix)
      XLdata.matrix
      
    })#end of reactive for XLdata
    
    output$XLmatrix <- renderPrint(XLdata())


  })#end of module server
}

应用代码

Import.Excel.Data.App <- function(){
  ui <- fluidPage(
   Import.Excel.Data.UI("File1"),
   textOutput("ABC.class"),
   verbatimTextOutput("ABC.matrix")
  )
  
  
  server <- function(input, output, session){
    ABC <- Import.Excel.Data.Server("File1")
    output$ABC.class <- renderText(class(ABC()))
    output$ABC.matrix <- renderPrint(ABC())
  }
  
  shinyApp(ui, server)
}

Import.Excel.Data.App()

你们非常亲密。您只需要 return 反应对象 XLdata,并在反应对象内部使用 req()。试试这个

Import.Excel.Data.Server <- function(id){
  moduleServer(id, function(input, output, session){
    ns <- session$ns
    observeEvent(eventExpr = input$AddExcelDataButton,
                 
                 insertUI(selector=paste0("#",ns("AddExcelDataButton")),
                          multiple=TRUE,
                          where = "afterEnd",
                          
                          ui = tags$hr(
                            tags$div(fileInput(inputId = ns(paste0("ExcelFile",input$AddExcelDataButton)),
                                               label = paste0("Path for File",input$AddExcelDataButton),
                                               multiple  = FALSE),
                                     style = "display:inline-block; vertical-align:top"
                            ),#end of tags$div
                            
                            tags$div(textInput(inputId = ns(paste0("ExcelSheetName",input$AddExcelDataButton)),
                                               label = paste0("Excel Sheet Name",input$AddExcelDataButton),
                                               value = "Data"),
                                     style = "display:inline-block; vertical-align:top"
                            ),#end of tags$div
                            
                            tags$div(textInput(inputId = ns(paste0("ExcelSheetRange",input$AddExcelDataButton)),
                                               label = paste0("Excel Sheet Range", input$AddExcelDataButton),
                                               value = "C6:AL10000"),
                                     style = "display:inline-block; vertical-align:top"
                            ),#end of tags$div
                            
                            
                            tags$div(checkboxInput(inputId = ns(paste0("ExcelFileCheck",input$AddExcelDataButton)),
                                                   label = paste0("Check to Use File", input$AddExcelDataButton),
                                                   value = TRUE),
                                     style = "display:inline-block; vertical-align:center"
                            )#end of tags$div
                            
                            
                          )#end of tags$hr  
                          
                 )#end of insertUI
    )#end of observeEvent
    
    XLdata <- reactive({
      req(input[[paste0("ExcelFile",input$AddExcelDataButton)]])
      for (i in 1: input$AddExcelDataButton)
      {
        temp.filepath <- input[[paste0("ExcelFile",i)]]$datapath
        temp.sheetname <- input[[paste0("ExcelSheetName",i)]]
        temp.sheetrange <- input[[paste0("ExcelSheetRange",i)]]
        temp.filecheck <- input[[paste0("ExcelFileCheck",i)]]
        row.temp <- cbind(temp.filepath, temp.sheetname, temp.sheetrange, temp.filecheck)
        
        
        
        ifelse(i<=1,
               {
                 XLdata.matrix <- row.temp
               },#end of if condition in ifelse i<=1
               {
                 XLdata.matrix <- rbind(XLdata.matrix, row.temp)
               } #end of else in ifelse i<=1
        )#end of ifelse brackets
        
      }#end of for-loop
      
      
      XLdata.matrix <- as.data.frame(XLdata.matrix)
      XLdata.matrix
      
    })#end of reactive for XLdata
    
    output$XLmatrix <- renderPrint(XLdata())
    
    return(XLdata)
    
  })#end of module server
}