无法在闪亮模块之间传递数据

can't communicate data between shiny modules

我正在尝试构建一个闪亮的应用程序,它使用多个模块在它们之间进行通信并共享数据。我试图创建一个可以复制的更简单的示例来说明我面临的问题。 第一个模块允许用户 select 数据集和 selected 数据集中的列,然后在 table 中显示该列。第一个模块的服务器部分 returns 关于 selected 列(最小值、平均值、最大值和标准差)的统计列表。 这个想法是使用这些统计数据在创建 textOutputs 的第二个模块中显示它们。问题是应用程序没有反应性。即使更改数据集和列,textOutputs 中的值也是相同的。

### Module 1
mod_selectVar_ui <- function(id){
  ns <- NS(id)
  tagList(
    selectInput(ns("dataset"), "Choose a dataset:",choices = c("rock", "pressure", "cars")),
    selectInput(ns("colonnes"),label = "Choose some columns", choices = NULL, multiple = FALSE),
    tableOutput(ns("table"))
  )
}

#'
#' 
mod_selectVar_server <- function(id){
  moduleServer(id, function(input, output, session){
    datasetInput <- reactive({
      switch(input$dataset,
             "rock" = rock,
             "pressure" = pressure,
             "cars" = cars)
    })
    
    observe({
      colonnes <- names(datasetInput())
      updateSelectInput( session, "colonnes", choices = colonnes)
    })
    
    data <- reactive({
      req(input$colonnes)
      datasetInput()[, input$colonnes]
    })
    output$table <- renderTable({
      head(data())
    })
    
    values <- reactive({
      list(
        meanVar = mean(data()),
        maxVar = max(data()),
        minVar = min(data()),
        sdVar = sd(data())
      )
    })
    return(values)
  })
}


### Module 2
mod_textOu_ui <- function(id){
  ns <- shiny::NS(id)
  shiny::tagList(
    shiny::textOutput(ns("txt"))
  )
}

mod_textOu_server <- function(id, texte){
  moduleServer(id,
               function(input, output, session){
                 output$txt <- renderText({
                   texte
                 })
               }
  )
}

### Main App
ui <- fluidPage(
  fluidRow(
    column(3,
           mod_textOu_ui("1")
    ),
    column(3,
           mod_textOu_ui("2")
    ),
    column(3,
           mod_textOu_ui("3")
    ),
    column(3,
           mod_textOu_ui("4")
    )
  ),
  fluidRow(
    mod_selectVar_ui("1")
  )
)

server <- function(input, output, session){
  values <- mod_selectVar_server("1")
  
  mod_textOu_server("1",values()$meanVar)
  
  mod_textOu_server("2",values()$maxVar)
  
  mod_textOu_server("3",values()$minVar)
  
  mod_textOu_server("4",values()$sdVar) 
}

shinyApp(ui ,server )
  1. 您的模块 mod_selectVar_server("1")mod_textOu_server("1",values()$meanVar) 的 ID 1 重复。所有 ID 都必须是唯一的,不建议使用数字。
  2. 正如@Limey 所说,您不能直接在服务器的顶层直接访问反应值。必须在反应性上下文中访问反应性值。将反应直接传递给函数,稍后在您的模块中访问它的值。
  3. 当您更改数据集时,数据将无效并且需要等待列名更新,因此我添加了 req(all(input$colonnes %in% names(datasetInput()))) 以防止短暂出现难看的红色警告。
### Module 1
mod_selectVar_ui <- function(id){
    ns <- NS(id)
    tagList(
        selectInput(ns("dataset"), "Choose a dataset:",choices = c("rock", "pressure", "cars")),
        selectInput(ns("colonnes"),label = "Choose some columns", choices = NULL, multiple = FALSE),
        tableOutput(ns("table"))
    )
}

#'
#' 
mod_selectVar_server <- function(id){
    moduleServer(id, function(input, output, session){
        datasetInput <- reactive({
            switch(input$dataset,
                   "rock" = rock,
                   "pressure" = pressure,
                   "cars" = cars)
        })
        
        observe({
            colonnes <- names(datasetInput())
            updateSelectInput(session, "colonnes", choices = colonnes)
        })
        
        data <- reactive({
            req(input$colonnes)
            req(all(input$colonnes %in% names(datasetInput())))
            datasetInput()[, input$colonnes]
        })
        output$table <- renderTable({
            head(data())
        })
        
        values <- reactive({
            list(
                meanVar = mean(data()),
                maxVar = max(data()),
                minVar = min(data()),
                sdVar = sd(data())
            )
        })
        return(values)
    })
}


### Module 2
mod_textOu_ui <- function(id){
    ns <- shiny::NS(id)
    shiny::tagList(
        shiny::textOutput(ns("txt"))
    )
}

mod_textOu_server <- function(id, texte, item){
    moduleServer(id,
                 function(input, output, session){
                     output$txt <- renderText({
                         texte()[[item]]
                     })
                 }
    )
}

### Main App
ui <- fluidPage(
    fluidRow(
        column(3,
               mod_textOu_ui("m1")
        ),
        column(3,
               mod_textOu_ui("m2")
        ),
        column(3,
               mod_textOu_ui("m3")
        ),
        column(3,
               mod_textOu_ui("m4")
        )
    ),
    fluidRow(
        mod_selectVar_ui("s1")
    )
)

server <- function(input, output, session){
    values <- mod_selectVar_server("s1")
    
    mod_textOu_server("m1",values, "meanVar")
    
    mod_textOu_server("m2",values, "maxVar")
    
    mod_textOu_server("m3",values, "minVar")
    
    mod_textOu_server("m4",values, "sdVar") 
}

shinyApp(ui ,server )