1

我正在开发一个依赖模块的 R Shiny 应用程序,希望我可以重新使用该模块来上传和显示两个不同的数据集。到目前为止,我的代码可以工作,但我认为我可以让它更简洁一些,因为我认为我没有正确地得到模块。我的意思是,我如何将这段代码片段(如下)从 app_server 移到模块服务器中,然后将 callModule 函数用于两个不同的数据集。同样,我可能需要删除此代码:tableOutput("metacontent")从应用程序 ui 中并在模块 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()

  })

}
4

2 回答 2

2

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

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

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

}

让我知道这是否回答了您的问题。

于 2019-12-09T07:34:58.167 回答
0

我就是这样做的。

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)

在此处输入图像描述

在此处输入图像描述

于 2019-12-27T15:03:13.790 回答