我正在尝试使用runtime: shiny_prerendered
构建一个数据密集,计算繁重的flex_dashboard。
我希望所有计算和过滤都在服务器端完成,在客户端进行渲染。
Shiny_prerendered允许我节省客户端和服务器的启动时间。在下面,我做了一个简化的版本。
我有一个很大的数据集(下面的faithful
)。我正在根据客户的需求过滤数据。过滤后的数据应在仪表板的所有图表和结果中使用。
我将库放在context="setup"
的用户界面context="render"
中(默认情况下不需要)。
我还想对按钮单击做出反应。所以我把
context="server"
个两个eventReactive
函数。一种用于数据过滤,另一种用于
选择直方图箱。
最后,对于每个结果(图或表),我将renderPlot
和renderTable
放入输出变量
context="server"
中将其显示在context="render"
中。在里面
渲染函数(图或表),我使用eventReactive
函数来过滤数据(并获取箱数)。
faithful_filtered()
进行过滤,并在下面的2 renderPlot
内部被调用。
1-这是否意味着数据被过滤两次?
2-操作是否完成两次?由于我的数据很大,所以我还有更多
实际项目中的输出,那将是非常缓慢且低效的。
3-如果以上两个问题是肯定的,我该如何首先获得一个按钮以过滤数据,然后在所有要绘制的绘图和表格中使用该数据?
这是原型代码:
---
title: "test shiny_prerendered with button"
output:
flexdashboard::flex_dashboard:
orientation: rows
editor_options:
chunk_output_type: console
runtime: shiny_prerendered
---
```{r, include=FALSE, message=FALSE, context="setup"}
library(tidyverse)
library(flexdashboard)
library(plotly)
library(shiny)
library(knitr)
```
Input {.sidebar data-width=300}
-------------------------------------
```{r, echo=FALSE, context="render"}
sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30)
textInput("min_e", "min eruptions", min(faithful$eruptions))
textInput("max_e", "max eruptions", max(faithful$eruptions))
actionButton(inputId = "OK", label = "OK")
```
```{r, context="server"}
nbins = eventReactive(input$OK, {input$bins})
faithful_filtered = eventReactive(input$OK, {faithful %>% filter(eruptions>=input$min_e,
eruptions<=input$max_e)})
```
Row
-----------------------------------------------------------------------
### Plot 1 - filter reactive, bin reactive
```{r, context="server"}
output$distPlot1 <- renderPlot({
x <- faithful_filtered()[, 2] # Old Faithful Geyser data
bins <- seq(min(x), max(x), length.out = nbins() + 1)
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
```
```{r, echo=FALSE}
plotOutput("distPlot1")
```
### Plot 2 - twice the number of bins - filter reactive, bin is not
```{r, context="server"}
output$distPlot2 <- renderPlot({
x <- faithful_filtered()[, 2] # Old Faithful Geyser data
bins <- seq(min(x), max(x), length.out = input$bins*2 + 1)
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
```
```{r, echo=FALSE}
plotOutput("distPlot2")
```
### Table - filter reactive
```{r, message=FALSE, context="server"}
output$table = renderTable({
head(faithful_filtered())
})
```
```{r, echo=FALSE}
tableOutput("table")
```
答案 0 :(得分:0)
我的理解是:
Reactive Log Visualizer是检查引擎盖下正在发生的事情的好地方。但是,在您当前的仪表板形式中(与rmarkdown一起使用shiny_prerendered),我无法使其运行。
仪表盘上的原始光泽效果如下所示:
library(tidyverse)
library(flexdashboard)
library(plotly)
library(shiny)
library(knitr)
shinyApp(ui = fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30),
textInput("min_e", "min eruptions", min(faithful$eruptions)),
textInput("max_e", "max eruptions", max(faithful$eruptions)),
actionButton(inputId = "OK", label = "OK")
),
mainPanel(
fluidRow(
column(4, plotOutput("distPlot1")),
column(4, plotOutput("distPlot2")),
column(4, tableOutput("table"))
)
)
)
),
server = function(input, output) {
nbins = eventReactive(input$OK, {input$bins})
faithful_filtered = eventReactive(input$OK, {
faithful %>% filter(eruptions >= input$min_e,
eruptions <= input$max_e)
})
output$distPlot1 <- renderPlot({
x <- faithful_filtered()[, 2] # Old Faithful Geyser data
bins <- seq(min(x), max(x), length.out = nbins() + 1)
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
output$distPlot2 <- renderPlot({
x <- faithful_filtered()[, 2] # Old Faithful Geyser data
bins <- seq(min(x), max(x), length.out = input$bins*2 + 1)
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
output$table = renderTable({
head(faithful_filtered())
})
}
)
您可以在此处运行反应式日志可视化器,但是-至少据我所知-要查看eventReactives中正在发生的事情并不容易。
我们可以使用reactive
和isolate
来重写仪表板:
library(tidyverse)
library(flexdashboard)
library(plotly)
library(shiny)
library(knitr)
shinyApp(ui = fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30),
textInput("min_e", "min eruptions", min(faithful$eruptions)),
textInput("max_e", "max eruptions", max(faithful$eruptions)),
actionButton(inputId = "OK", label = "OK")
),
mainPanel(
fluidRow(
column(4, plotOutput("distPlot1")),
column(4, plotOutput("distPlot2")),
column(4, tableOutput("table"))
)
)
)
),
server = function(input, output) {
nbins = reactive({input$OK
isolate(input$bins)})
faithful_filtered = reactive({input$OK
faithful %>% filter(eruptions >= isolate(input$min_e),
eruptions <= isolate(input$max_e))
})
output$distPlot1 <- renderPlot({
x <- faithful_filtered()[, 2] # Old Faithful Geyser data
bins <- seq(min(x), max(x), length.out = nbins() + 1)
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
output$distPlot2 <- renderPlot({
x <- faithful_filtered()[, 2] # Old Faithful Geyser data
bins <- seq(min(x), max(x), length.out = input$bins*2 + 1)
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
output$table = renderTable({
head(faithful_filtered())
})
}
)
在这里,反应式日志可视化器基本上可以确认反应式仅在单击按钮后才执行。
我希望使用eventReactive的其他两种方法的行为几乎相同,但是我尚无法确定。