将 reactive() 元素传递到用户定义的函数中,该函数生成 shinyApp()

Pass reactive() element into user defined function that makes a shinyApp()

我正在制作一个闪亮的仪表板,其中包含许多表,这些表的外观和行为应该相同,但包含不同的数据。为了使我的代码更加模块化,我编写了一个函数来保存 shinyApp() 调用,以便它可以被重用。 Here is a link to the official shiny documentation showing the use of shinyApp() within a user defined function.

该函数在一定程度上起作用,因为它呈现数据表,但它不会对输入的反应数据帧的变化做出反应。

这是我编写的函数,以及我使用的库和数据表应响应的边栏:

---
title: "Test"
runtime: shiny
output:
  flexdashboard::flex_dashboard: 
    navbar:
    orientation: rows 
    vertical_layout: fill
---
```{r packages, include = FALSE}
library(flexdashboard)
library(DT)
library(dplyr)
library(shiny)
library(datasets)

test_data <- datasets::CO2

data_chart <- function(shiny_data, col_names){
    shinyApp(
        ui = fluidPage(
            DT::dataTableOutput("results")
        ),
        server = function(input, output, session) {
            output$results <- DT::renderDataTable(  
                datatable(      
                shiny_data,
                filter = 'top',
                colnames = col_names,
                rownames = FALSE,
                    options = list(
                        dom = 'lptpi',
                        scrollY = '',
                        order = list(3, 'desc')
                    )
                )
            )
        }
    )
}
```

Header
===

Sidebar {.sidebar}
---

```{r}
checkboxGroupInput(
    inputId = 'Plant1', 
    label = h4("Age Group"),
    choices = list('Qn1', 'Qn2', 'Qn3', 'Qc1', 'Qc2', 'Qc3', 'Mn1', 'Mn2', 'Mn3', 'Mc1', 'Mc2', 'Mc3'),
    selected = c('Qn1', 'Qn2', 'Qn3', 'Qc1', 'Qc2', 'Qc3', 'Mn1', 'Mn2', 'Mn3', 'Mc1', 'Mc2', 'Mc3')
)
```

Row
---

```{r}
data_1 = reactive({test_data %>% 
    filter(Plant %in% input$Plant1) %>% 
    data.frame()
    })

data_chart(test_data, c('Plant', 'Type', 'Treatment', 'Conc', 'Uptake'))

我认为问题与以下事实有关:在函数中,我将反应数据集 "shiny_data()" 称为 "shiny_data"(不带括号),这使得它表现得静态。但是,我尝试添加括号,但出现错误:

ERROR: could not find function "shiny_data()"

此外,我尝试用 reactive({}) 包装代码的各个部分,以尝试将数据显式定义为反应式,但没有成功。

我相信这不是在函数中使用 shinyApp() 的问题,因为当我创建一个函数时,我已经硬编码了反应性 data_1() 数据框,它会做出反应到侧边栏的变化。这是此结果的示例(函数与上面完全相同,但不是将 shiny_data 传递给函数,而是将 data_1() 硬编码在):

Row
---
```{r}
data_chart2 <- function(col_names){
    shinyApp(
        ui = fluidPage(
        DT::dataTableOutput("results")
        ),
        server = function(input, output, session) {
            output$results <- DT::renderDataTable(  
                serverTable <- datatable(       
                    data_1(),
                    filter = 'top',
                    colnames = col_names,
                    rownames = FALSE,
                    options = list(
                        dom = 'lptpi',
                        scrollY = '',
                        order = list(3, 'desc')
                    )
                )
            )
        }
    )
}

data_chart2(c('Plant', 'Type', 'Treatment', 'Conc', 'Uptake'))
```

正如您在提供的两个示例中所看到的,呈现数据表中的数据仅在函数中显式调用反应数据集时才会做出反应。有什么方法可以在用户定义的函数输入数据 into/called 时将其视为反应元素?

谢谢你的帮助!

为了能够将 reactive 传递给函数,您需要在传递时不带括号。

data_chart(data_1, c('Plant', 'Type', 'Treatment', 'Conc', 'Uptake'))

您可以在带有 参数名称 + 括号 的函数中使用它:shiny_data()

完整 data_chart 功能:

data_chart <- function(shiny_data, col_names){
  shinyApp(
    ui = fluidPage(
      DT::dataTableOutput("results")
    ),
    server = function(input, output, session) {
      output$results <- DT::renderDataTable(  
        datatable(      
          shiny_data(),
          filter = 'top',
          colnames = col_names,
          rownames = FALSE,
          options = list(
            dom = 'lptpi',
            scrollY = '',
            order = list(3, 'desc')
          )
        )
      )
    }
  )
}

输出