flex_dashboard shiny_prerendered 带有 eventReactive 过滤
flex_dashboard shiny_prerendered with eventReactive filtering
我正在尝试使用 runtime: shiny_prerendered
构建一个数据繁重、计算繁重的闪亮 flex_dashboard。
我希望所有计算和过滤都在服务器端完成,渲染在客户端完成。
shiny_prerendered 让我可以节省客户端和服务器的启动时间。在下面,我有一个我所做的简化版本。
我有一个大数据集(下面的 faithful
)。我正在根据客户的需要过滤该数据。筛选后的数据应该用于仪表板的所有图表和结果。
我将库放在 context="setup"
,UI 和 context="render"
(不需要,因为它是默认设置)。
我还想对按钮点击进行过滤和绘图。所以我投入
context="server"
两个 eventReactive
函数。一种用于过滤数据,另一种用于
直方图箱的选择。
最后,对于每个结果(绘图或 table),我将 renderPlot
和 renderTable
放入输出变量
在 context="server"
中并在 context="render"
中显示它们。在里面
渲染函数(Plot 或 Table),我使用过滤数据的 eventReactive
函数(并获取 bin 的数量)。
faithful_filtered()
做过滤,在下面2renderPlot
里面调用。
1-这是否意味着数据被过滤了两次?
2- 手术进行了两次吗?由于我的数据非常大,所以我还有更多
在实际项目中输出,那将是非常缓慢和低效的。
3- 如果以上 2 个问题是肯定的,我如何首先获得过滤数据的按钮,然后在所有绘图中使用该数据并呈现 tables?
原型代码如下:
---
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")
```
我的理解是:
- 数据只在eventReactive初始化时过滤一次,
之后,通过单击操作按钮
进行每次更新
- 单击操作按钮时,我希望操作执行一次,而不是两次。
- 因此我认为按钮的行为符合预期。
检查引擎盖下发生的事情的好地方是 Reactive Log Visualizer。但是,在您仪表板的当前形式中(在 shiny_prerendered 的 rmarkdown 中)我无法得到它 运行ning.
仪表板的香草闪亮方法如下所示:
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
s 和 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 的其他两种方法的行为几乎相同,但我还无法确定。
我正在尝试使用 runtime: shiny_prerendered
构建一个数据繁重、计算繁重的闪亮 flex_dashboard。
我希望所有计算和过滤都在服务器端完成,渲染在客户端完成。
shiny_prerendered 让我可以节省客户端和服务器的启动时间。在下面,我有一个我所做的简化版本。
我有一个大数据集(下面的 faithful
)。我正在根据客户的需要过滤该数据。筛选后的数据应该用于仪表板的所有图表和结果。
我将库放在 context="setup"
,UI 和 context="render"
(不需要,因为它是默认设置)。
我还想对按钮点击进行过滤和绘图。所以我投入
context="server"
两个 eventReactive
函数。一种用于过滤数据,另一种用于
直方图箱的选择。
最后,对于每个结果(绘图或 table),我将 renderPlot
和 renderTable
放入输出变量
在 context="server"
中并在 context="render"
中显示它们。在里面
渲染函数(Plot 或 Table),我使用过滤数据的 eventReactive
函数(并获取 bin 的数量)。
faithful_filtered()
做过滤,在下面2renderPlot
里面调用。
1-这是否意味着数据被过滤了两次?
2- 手术进行了两次吗?由于我的数据非常大,所以我还有更多
在实际项目中输出,那将是非常缓慢和低效的。
3- 如果以上 2 个问题是肯定的,我如何首先获得过滤数据的按钮,然后在所有绘图中使用该数据并呈现 tables?
原型代码如下:
---
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")
```
我的理解是:
- 数据只在eventReactive初始化时过滤一次, 之后,通过单击操作按钮 进行每次更新
- 单击操作按钮时,我希望操作执行一次,而不是两次。
- 因此我认为按钮的行为符合预期。
检查引擎盖下发生的事情的好地方是 Reactive Log Visualizer。但是,在您仪表板的当前形式中(在 shiny_prerendered 的 rmarkdown 中)我无法得到它 运行ning.
仪表板的香草闪亮方法如下所示:
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
s 和 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 的其他两种方法的行为几乎相同,但我还无法确定。