用于在 r shiny 中输入 csv/tsv/txt 文件的模块

module for inputting csv/tsv/txt files in rshiny

我正在开发一个 R Shiny 应用程序,它将依赖一个模块,希望我可以重新使用该模块来上传和显示两个不同的数据集。截至目前,我的代码可以工作,但我认为我可以使它更简洁一些,因为我认为我没有得到正确的模块。我的意思是,如何将此代码片段(如下)移出 app_server 并移入模块服务器,然后将 callModule 函数用于两个不同的数据集。同样,我可能需要从应用程序 ui 中删除此代码:tableOutput("metacontent"),并在模块 ui 中调用该代码。请参阅代码段下方的模块 ui、模块服务器、应用程序 ui 和应用程序服务器。有什么建议么?谢谢!

#code snippet
output$metacontents <- renderTable({
    metafile()

  })
# Module UI
mod_dataInput_ui <- function(id, label) {
  # Create a namespace function using the provided id
  ns <- NS(id)

  tagList(

    # Input: Select a file ----
    fileInput(ns("id"), label, 
              multiple = FALSE,
              accept = c("text/csv", 
                         "text/comma-separated-values,text/plain",
                         ".csv",
                         ".tsv")),

    # Input: Select separator ----
    radioButtons(ns("sep"), "Separator",
                 choices = c(Comma = ",",
                             Tab = "\t"),
                 selected = "\t"))
}

# Module Server
mod_dataInput_server <- function(input, output, session) {

  userFile <- reactive({
    validate(need(input$id !="", "Please import a data file"))
    input$id
  })    

  datafile <- reactive({
    utils::read.table(userFile()$datapath,
                      header = FALSE,
                      sep = input$sep,
                      row.names = NULL,
                      skip = 1,
                      stringsAsFactors = FALSE)

  })

}
#App UI
app_ui <- function() {
  tagList(
    # Leave this function for adding external resources
    golem_add_external_resources(),
    # List the first level UI elements here 
    navbarPage("Tinsel",
               tabPanel("Load Data",
                        sidebarPanel(mod_dataInput_ui("dataInput_ui_meta", tags$div("User META data", tags$br(), "(.csv, .tsv, or .txt file format)")), helpText("Can add help text here"),
                                     # Horizontal line ----
                                     tags$hr(style="border-color: black;"),
                                     mod_dataInput_ui("dataInput_ui_gene", tags$div("User GENETIC data", tags$br(), "(.csv, .tsv, or .txt file format)")),
                                     tags$hr(style="border-color: black;")),
                        mainPanel(
                          tabsetPanel(
                            tabPanel("Meta Data",
                                     tableOutput("metacontents")),
                            tabPanel("Genetic Data",
                                     tableOutput("genecontents"))
                          )))
    )
  )
}
#App server
app_server <- function(input, output, session) {
  # List the first level callModules here


  metafile <- callModule(mod_dataInput_server, "dataInput_ui_meta")

  output$metacontents <- renderTable({
    metafile()

  })

  genefile <- callModule(mod_dataInput_server, "dataInput_ui_gene")

  output$genecontents <- renderTable({
    genefile()

  })

}

据我所知,您已正确获取模块:您在两个不同的 ID 上重复使用 UI 和服务器以进行数据导入。

您可以通过为 table 部分创建模块来优化您所做的工作,因此编写:

# mod_table.R 

mod_table_ui <- function(id, name){
  ns <- NS(id)
  tabPanel(
    name,
    tableOutput(ns("metacontents"))
  )
}

# Module Server

#' @rdname mod_table
#' @export
#' @keywords internal

mod_table_server <- function(input, output, session, file){
  ns <- session$ns
  output$metacontents <- renderTable({
    file()
  })
}

然后在app_ui:

#' @import shiny
app_ui <- function() {
  tagList(
    # Leave this function for adding external resources
    golem_add_external_resources(),
    # List the first level UI elements here 
    navbarPage(
      "Tinsel",
      tabPanel(
        "Load Data",
        sidebarPanel(
          mod_dataInput_ui(
            "dataInput_ui_meta", 
            tags$div(
              "User META data", 
              tags$br(), 
              "(.csv, .tsv, or .txt file format)"
            )
          ), 
          helpText("Can add help text here"),
          # Horizontal line ----
          tags$hr(style="border-color: black;"),
          mod_dataInput_ui(
            "dataInput_ui_gene", 
            tags$div(
              "User GENETIC data", 
              tags$br(), 
              "(.csv, .tsv, or .txt file format)"
            )
          ),
          tags$hr(style="border-color: black;")
        ),
        mainPanel(
          tabsetPanel(
            mod_table_ui("table_ui_1", "Meta Data"),
            mod_table_ui("table_ui_2", "Genetic Data")
          )
        )
      )
    )
  )
}

和app_server:

app_server <- function(input, output, session) {
  # List the first level callModules here

  metafile <- callModule(mod_dataInput_server, "dataInput_ui_meta")

  callModule(mod_table_server, "table_ui_1", metafile)

  genefile <- callModule(mod_dataInput_server, "dataInput_ui_gene")

  callModule(mod_table_server, "table_ui_2", genefile)

}

如果这回答了您的问题,请告诉我。

我就是这样做的。

library(shiny)
library(ggplot2)
#ui.R
ui <- fluidPage(
  titlePanel("My shiny app"), sidebarLayout(
sidebarPanel(
  helpText("This app shows how a user can upload a csv file. Then, plot the data.
          Any file can be uploaded but analysis is only available
          if the data is in same format as the sample file, downloadable below
          "),
  a("Data to be plotted", href="https://www.dropbox.com/s/t3q2eayogbe0bgl/shiny_data.csv?dl=0"),
  tags$hr(),
  fileInput("file","Upload the file"), 
  h5(helpText("Select the read.table parameters below")),
  checkboxInput(inputId = 'header', label = 'Header', value = TRUE),
  checkboxInput(inputId = "stringAsFactors", "stringAsFactors", FALSE),
  br(),
  radioButtons(inputId = 'sep', label = 'Separator', choices = c(Comma=',',Semicolon=';',Tab='\t', Space=''), selected = ',')
),
mainPanel(
  uiOutput("tb"),
  plotOutput("line")             
)
)
)

#server.R
server <- function(input,output){
data <- reactive({


file1 <- input$file
if(is.null(file1)){return()} 

read.table(file=file1$datapath, sep=input$sep, header = input$header, stringsAsFactors = input$stringAsFactors)})

output$filedf <- renderTable({
if(is.null(data())){return ()}
input$file
}) 

output$sum <- renderTable({
if(is.null(data())){return ()}
summary(data())
})

output$table <- renderTable({
if(is.null(data())){return ()}
data()
})

output$line <- renderPlot({
if (is.null(data())) { return() }
print(ggplot(data(), aes(x=date, y=aa)) + geom_line()+ facet_wrap(~station)) })

output$tb <- renderUI({if(is.null(data()))
h5()               
else
  tabsetPanel(tabPanel("About file", tableOutput("filedf")),tabPanel("Data", tableOutput("table")),tabPanel("Summary", tableOutput("sum")))
})
}


shinyApp(ui = ui, server = server)