r - 如何对 Shiny 的 ObserveEvent 中执行的所有计算使用“withProgress”?
问题描述
嗨,感谢您阅读我,我正在 Shiny 中制作一个应用程序,该应用程序使用神经网络计算预测图。模型(和图形)加载大约需要 9 秒,我希望在该等待时间内出现一个进度条,但我无法让它正常工作,因为显然它只出现在图形。你知道我可以让所有计算的栏出现吗?
代码(和数据)如下:
library(readxl)
library(dplyr)
library(shiny)
library(highcharter)
library(forecast)
datos <- data.frame(
Servicio = sample(c("Servicio 1", "Servicio 2", "Servicio 3"), 162, replace = TRUE),
Año_mes = seq(as.Date("1980-01-01"), as.Date("2020-05-31"), by = "quarter"),
servs = rnorm(162, mean = 500)
) |>
setNames(c("Servicio", "Año_mes", "Número de Servicios"))
datos1 <- datos |>
group_by(Año_mes, Servicio) |>
summarise(total = sum(`Número de Servicios`))
datos_select <- datos |>
group_by(Servicio) |>
summarise(total = sum(datos$`Número de Servicios`))
datos_select <- datos_select$Servicio
datos_select
ui <- fluidPage(
column(
width = 6,
selectInput("var",
"Escoge un servicio a modelar", choices = datos_select
),
numericInput("rezagosnoest", "Escoge un número de rezagos no estacionales:",1, min = -1000, max = 1000),
numericInput("rezagossiest", "Escoge un número de rezagos estacionales:",1, min = -1000, max = 1000),
numericInput("neuronas", "Escoge la cantidad de neuronas usadas para el cálculo:",1, min = 1, max = 1000),
#numericInput("futuros", "Escoge el número de periodos (meses) a pronosticar:",1, min = 1, max = 1000),
actionBttn(
inputId = "modelar",
label = "Generar pronóstico",
style = "bordered",
color = "success",
icon = icon("sliders")
)),
column(width = 6,
highchartOutput("grafico"))
)
server <- function(input, output){
observeEvent(
input$modelar,{
filtrado <- datos1 |>
filter(Servicio == input$var)
temporal <- ts(filtrado$total, start = 2017, frequency = 12)
set.seed(50)
modelo <- nnetar(temporal, p=input$rezagossiest,P=input$rezagosnoest,
size=input$neuronas)
nnetforecast <- forecast(modelo, h = 12, PI = T)
output$grafico <- renderHighchart({
withProgress(message = 'Calculando el modelo',
detail = 'Espera un momento...', value = 0, {
for (i in 1:15) {
incProgress(1/15)
}
})
hchart(nnetforecast)
})
}
)
}
shinyApp(ui, server)
解决方案
我认为你不能添加一个精确的进度条而不抽动使用的函数来给你关于实际进度的反馈,或者有另一个函数来根据用户输入来估计所需的时间。
如果您没有时间深入研究,我鼓励您使用以下一个或两个软件包:
-https://dreamrs.github.io/shinybusy/
-https://github.com/daattali/shinycssloaders
两者都提供了良好的服务,让用户知道您的应用程序没有崩溃。
我提供以下示例,添加一个条件面板以隐藏绘图,直到单击操作按钮。
添加 CSS 加载器和条件面板
library(shinycssloaders)
library(shiny)
ui <- fluidPage(
column(
width = 6,
selectInput("var",
"Escoge un servicio a modelar", choices = datos_select
),
numericInput("rezagosnoest", "Escoge un número de rezagos no estacionales:",1, min = -1000, max = 1000),
numericInput("rezagossiest", "Escoge un número de rezagos estacionales:",1, min = -1000, max = 1000),
numericInput("neuronas", "Escoge la cantidad de neuronas usadas para el cálculo:",1, min = 1, max = 1000),
#numericInput("futuros", "Escoge el número de periodos (meses) a pronosticar:",1, min = 1, max = 1000),
actionBttn(
inputId = "modelar",
label = "Generar pronóstico",
style = "bordered",
color = "success",
icon = icon("sliders")
)),
column(width = 6,
conditionalPanel("input.modelar > 0",
shinycssloaders::withSpinner(
highchartOutput("grafico")
),
)
)
)
server <- function(input, output){
observeEvent(
input$modelar,{
output$grafico <- renderHighchart({
filtrado <- datos1 |>
filter(Servicio == input$var)
temporal <- ts(filtrado$total, start = 2017, frequency = 12)
set.seed(50)
modelo <- nnetar(temporal, p=input$rezagossiest,P=input$rezagosnoest,
size=input$neuronas)
nnetforecast <- forecast(modelo, h = 12, PI = T)
hchart(nnetforecast)
})
})
}
shinyApp(ui, server)
这导致我进入另一个问题,您正在使用操作按钮作为提交按钮。如您所见,问题在于输入更改激活了反应性,这就是我添加的原因isolate()
:
防止反应
server <- function(input, output){
observeEvent(
input$modelar,{
output$grafico <- renderHighchart({
isolate({
filtrado <- datos1 |>
filter(Servicio == input$var)
temporal <- ts(filtrado$total, start = 2017, frequency = 12)
set.seed(50)
modelo <- nnetar(temporal, p=input$rezagossiest,P=input$rezagosnoest,
size=input$neuronas)
nnetforecast <- forecast(modelo, h = 12, PI = T)
hchart(nnetforecast)
})
})
})
}
如果您仍想添加进度条,我想您可以将其与图表的呈现并行添加:
并行进度条的最终答案
library(readxl)
library(dplyr)
library(shiny)
library(highcharter)
library(forecast)
library(shinycssloaders)
datos <- data.frame(
Servicio = sample(c("Servicio 1", "Servicio 2", "Servicio 3"), 162, replace = TRUE),
Año_mes = seq(as.Date("1980-01-01"), as.Date("2020-05-31"), by = "quarter"),
servs = rnorm(162, mean = 500)
) |>
setNames(c("Servicio", "Año_mes", "Número de Servicios"))
datos1 <- datos |>
group_by(Año_mes, Servicio) |>
summarise(total = sum(`Número de Servicios`))
datos_select <- datos |>
group_by(Servicio) |>
summarise(total = sum(datos$`Número de Servicios`))
datos_select <- datos_select$Servicio
datos_select
ui <- fluidPage(
column(
width = 6,
selectInput("var",
"Escoge un servicio a modelar", choices = datos_select
),
numericInput("rezagosnoest", "Escoge un número de rezagos no estacionales:",1, min = -1000, max = 1000),
numericInput("rezagossiest", "Escoge un número de rezagos estacionales:",1, min = -1000, max = 1000),
numericInput("neuronas", "Escoge la cantidad de neuronas usadas para el cálculo:",1, min = 1, max = 1000),
#numericInput("futuros", "Escoge el número de periodos (meses) a pronosticar:",1, min = 1, max = 1000),
actionBttn(
inputId = "modelar",
label = "Generar pronóstico",
style = "bordered",
color = "success",
icon = icon("sliders")
)),
column(width = 6,
conditionalPanel("input.modelar > 0",
shinycssloaders::withSpinner(
highchartOutput("grafico")
),
)
)
)
server <- function(input, output){
observeEvent(
input$modelar,{
output$grafico <- renderHighchart({
isolate({
filtrado <- datos1 |>
filter(Servicio == input$var)
temporal <- ts(filtrado$total, start = 2017, frequency = 12)
set.seed(50)
modelo <- nnetar(temporal, p=input$rezagossiest,P=input$rezagosnoest,
size=input$neuronas)
nnetforecast <- forecast(modelo, h = 12, PI = T)
hchart(nnetforecast)
})
})
})
observeEvent(input$modelar,{
withProgress(message = 'Calculando el modelo',
detail = 'Espera un momento...', value = 0, {
for (i in 1:15) {
Sys.sleep(1)
incProgress(i/15)
}
})
})
}
shinyApp(ui, server)
最终推荐
进入 nnet 并添加一些进度指示器(迭代或其他东西)将其拉出并与 cssloader 结合使用以涵盖绘图时间。
推荐阅读
- api - 如何使用 discord api 发送图像消息?
- nginx - Nginx:需要 http_name 域的映射函数
- reactjs - Uploading a CSV and Creating a chart - react
- javascript - 将特定颜色交换为图像 javascript
- javascript - document.getElementById 没有在我的 React 组件中动态更改样式
- r - 如果在函数中,evalq 如何在正确的环境中获取文件
- linux - 寻找一种在一个衬里中搜索多个字符串以查找 zipgrep 的方法
- github - 有条件地在 GitHub 操作工作流中附加字符串
- spring-boot - spring boot hibernate缓存相关查询
- java - 转换通量
进入通量