首页 > 解决方案 > 将闪亮的渲染输出放在其他函数中

问题描述

所以我正在制作一个闪亮的应用程序,它接受多个输入并生成这些输入的多个图和表。

制作一张表的示例 RenderTable 代码如下:

output$Table1 <- 
      renderTable(data.frame(Shape = c("\u25CF", "\u25B2", "\u25FC", ""),
                             "Genes" = c(input$custom_genes1, "Mean"),
                              Analysed_values = c(t(analysis1()), mean(analysis1()))), 
                              striped = TRUE, bordered = TRUE, hover = TRUE)

其中 Shape 是绘图上的符号,“Genes”是使用 selectizeInput 选择的基因,而 analysis1() 是代码中前面定义的反应计算的结果。

但是,我有 8-9 个表需要根据各种复选框等显示。我不想复制粘贴代码并替换所有相关值,而是想创建一个可以用来快速显示所有表的函数,如果我需要更改格式或稍后添加任何内容,我可以只编辑函数而不是单独编辑每个表。

我尝试使用以下代码制作可重用的功能:

construct_table <- function(genes_select, dataset){
    renderTable(data.frame(Shape = c("\u25CF", "\u25B2", "\u25FC", ""),
                          "Genes" = genes_select,
                           Analysed_values = c(t(dataset), mean(dataset))), 
                           striped = TRUE, bordered = TRUE, hover = TRUE)
  }

然后更容易直接调用每个表:

output$Table1 <- construct_table(input$custom_genes1, analysis1())

这适用于使用初始输入值创建表,但不会使表反应。

如何在普通函数中调用 renderTable 反应函数,或者是否有另一个我忽略的反应函数可以在其中嵌套 renderTable 函数,其工作方式与普通函数相同?

标签: rshiny

解决方案


简单地在任何地方添加output$Table1 <- construct_table(input$custom_genes1, analysis1())调用是行不通的,因为analysis()它是一个反应变量,取决于用户可以更改的其他输入。因此analysis()可以在反应式上下文中使用。IE。从内部observe, observeEvent, reactive, eventReactive or inside any renderXXX call ex: renderTable, renderPlot...

当我们调用 时output$Table1 <- construct_table(input$custom_genes1, analysis1()),我们是analysis1()外部使用会导致错误的反应式上下文。解决方案是专门设计用于模块化代码的 Shiny Modules,这似乎是这里的目标。

https://shiny.rstudio.com/articles/modules.html

这是一个例子,

dataset = mtcars

generatePlot = function(input,output,session,data){
  output$plot = renderPlot({
    plot(data()$hp,data()$mpg)
    })
}


generateUI = function(id){
  ns = NS(id)
  plotOutput(ns("plot"))
}

shinyApp(
  ui = {
    fluidPage(
      sliderInput("slider","MPG filter",min(dataset$mpg),max(dataset$mpg),dataset$mpg),
      generateUI("mod1"),
      generateUI("mod2")
    )
  },
  server = function(input,output,session){

    data = eventReactive(input$slider,{
      dataset%>%
        dplyr::filter(between(mpg,input$slider[[1]],input$slider[[2]]))%>%
        return(.)
    })

    callModule(generatePlot,"mod1",data = data)
    callModule(generatePlot,"mod2",data = data)

  }
)

generateUI您可以通过简单地添加一个新调用和一个新callModule调用来添加更多相同的图。


推荐阅读