温馨提示:本文翻译自stackoverflow.com,查看原文请点击:r - Pass reactive() element into user defined function that makes a shinyApp()
flexdashboard r r-markdown shiny

r - 将react()元素传递到用户定义的函数中,该函数可生成ShinyApp()

发布于 2020-03-27 11:04:20

我正在制作一个闪亮的仪表板,其中包含许多应显示且行为相同的表,但包含不同的数据。为了使我的代码更具模块化,我编写了一个函数,该函数将保存shinyApp()调用,以便可以重用它。这是指向官方的闪亮文档的链接,该文档显示了用户定义的函数中shinyApp()的用法

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

Here is the function I have written, along with the libraries I've used and the sidebar that the datatable should be reacting to:

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

I think the problem has something to do with the fact that within the function, I refer to the reactive data set "shiny_data()" as "shiny_data" (without parenthesis), which makes it behave statically. However, I have tried adding the parenthesis and I get the error:

ERROR: could not find function "shiny_data()"

Furthermore, I have tried wrapping various sections of the code with reactive({}) to try to explicitly define the data as reactive, but with no luck.

I'm confident this isn't an issue with having the shinyApp() within a function, because when I make a function that I have hard coded the reactive data_1() data frame, it reacts to changes in the sidebar. Here is an example of this result (the function is exactly the same as above, but instead of passing shiny_data into the function, data_1() is hardcoded in):

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'))
```

As you can see in both provided examples, the data in the rendered datatable only reacts when the reactive dataset is explicitly called in the function. is there any way that at the time the data is input into/called by the user defined function, it can be treated as a reactive element?

Thank you for you help!

查看更多

查看更多

提问者
Joe Short
被浏览
316
GyD 2019-07-04 00:19

To be able to pass a reactive to a function, you need to pass it without brackets.

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')
          )
        )
      )
    }
  )
}

输出量

输出