在 Shiny R 中绘制图形;使用重复循环绘制数据以进行自动分析
Plotting graphs in Shiny R; using a repeat loop to plot data for automated analysis
编辑
我正在构建一个闪亮的应用程序,其中一个组件将包含自动数据分析。我对它的主要用途是访问 API 以收集数据并对其进行后续分析。此操作在 repeat
循环内发生,延迟 5 分钟(尽管这可以由应用程序的用户指定)。延迟结束后,将再次访问 API 并重新开始该过程。这对我来说效果很好,因为我 return 我的 plots/tables 作为主控制台中的列表。
但是,我无法在 Shiny 应用程序中执行它。我无法提供 API 信息,但出于所有意图和目的,这里是一个使用 mpg
数据集的可复制示例。
下面是一个使用动作按钮生成的绘图示例,没有使用重复循环。每次单击操作按钮时,图形将更新为当前系统时间:
以及生成此代码的代码:-
library(shiny)
library(ggplot2)
ui<-fluidPage(
titlePanel('Minimal example'),
tabsetPanel(
tabPanel("Example",
#summary
sidebarPanel(width = 4,
h5("The default interval for the analysis refresh is 5 minutes. If you wish to change this, please do so in the box below:"),
numericInput("intervaltime","Input refresh interval:",5),
br(),
h5("Press 'Run Analysis' button below to start automated analysis"),
actionButton("automatedanalysis", "Run Analysis")),
mainPanel(
h4("An example plot"),
plotOutput("example_plot", width = "100%"),
h4("Some text with updated system time"),
textOutput("example_text")
)
)))
server<-function(input,output,session){
observeEvent(input$automatedanalysis,{
#interval=input$intervaltime*60
#repeat{
currenttime<-Sys.time()
p<-ggplot(mpg, aes(displ, hwy, colour = class)) +
geom_point()+ggtitle(paste0("graph made at: ",currenttime))# adds on the current time
output$example_plot<-renderPlot({
return(p)
})
output$example_text<-renderText({
print(paste0("The current system time is: ", Sys.time())) #a check to know that it is working
})
#Sys.sleep(interval)
#}
})
}
shinyApp(ui, server)
然而,当我使用 UI 中的数字输入来切换间隔计时器时,我将重复循环投入使用,它不再起作用。这是非工作代码:-
ui<-fluidPage(
titlePanel('Minimal example'),
tabsetPanel(
tabPanel("Example",
#summary
sidebarPanel(width = 4,
h5("The default interval for the analysis refresh is 5 minutes. If you wish to change this, please do so in the box below:"),
numericInput("intervaltime","Input refresh interval:",5),
br(),
h5("Press 'Run Analysis' button below to start automated analysis"),
actionButton("automatedanalysis", "Run Analysis")),
mainPanel(
h4("An example plot"),
plotOutput("example_plot", width = "100%"),
h4("Some text with updated system time"),
textOutput("example_text")
)
)))
server<-function(input,output,session){
observeEvent(input$automatedanalysis,{
interval=input$intervaltime*60
repeat{
currenttime<-Sys.time()
p<-ggplot(mpg, aes(displ, hwy, colour = class)) +
geom_point()+ggtitle(paste0("graph made at: ",currenttime))# adds on the current time
output$example_plot<-renderPlot({
return(p)
})
output$example_text<-renderText({
print(paste0("The current system time is: ", Sys.time())) #a check to know that it is working
})
Sys.sleep(interval)
}
})
}
shinyApp(ui, server)
没有图表或文本输出出现。
再一次,这在 Shiny App 之外工作正常,但我需要它作为我正在开发的 Shiny App 中的一个功能。
总而言之,我怎样才能让它工作,以便在单击操作按钮时,在间隔期结束后刷新分析?
您应该看看 invalidateLater
或 reactiveTimer
函数。
我在以下示例中使用 invalidateLater
(注意:该函数将毫秒作为第一个参数)。
你也不应该在观察者中放置任何输出,创建一个 reactiveVal
/ reactiveValues
对象并在每个新的时间间隔填充它。然后您可以在应用程序的任何地方使用该对象。
我还将 observeEvent
更改为正常的 observe
,否则它只会在单击按钮时触发。现在,观察者触发,当单击 Button 时,间隔滑块发生变化,并且间隔已经过去。
library(shiny)
library(ggplot2)
ui<-fluidPage(
titlePanel('Minimal example'),
tabsetPanel(
tabPanel("Example",
sidebarPanel(width = 4,
h5("The default interval for the analysis refresh is 5 minutes. If you wish to change this, please do so in the box below:"),
numericInput("intervaltime","Input refresh interval:",5),
br(),
h5("Press 'Run Analysis' button below to start automated analysis"),
actionButton("automatedanalysis", "Run Analysis")),
mainPanel(
h4("An example plot"),
plotOutput("example_plot", width = "100%"),
h4("Some text with updated system time"),
textOutput("example_text")
)
)))
server<-function(input,output,session){
rv <- reactiveVal(NULL)
observe({
interval = input$intervaltime*1000
invalidateLater(interval, session)
req(input$automatedanalysis)
print("Fill ReactiveVal")
mpg$hwy <- mpg$hwy * runif(nrow(mpg))
rv(mpg)
})
output$example_plot<-renderPlot({
req(rv())
currenttime<-Sys.time()
print("Plot Code")
ggplot(rv(), aes(displ, hwy, colour = class)) +
geom_point()+ggtitle(paste0("graph made at: ",currenttime))
})
output$example_text<-renderText({
print(paste0("The current system time is: ", Sys.time())) #a check to know that it is working
})
}
shinyApp(ui, server)
编辑
我正在构建一个闪亮的应用程序,其中一个组件将包含自动数据分析。我对它的主要用途是访问 API 以收集数据并对其进行后续分析。此操作在 repeat
循环内发生,延迟 5 分钟(尽管这可以由应用程序的用户指定)。延迟结束后,将再次访问 API 并重新开始该过程。这对我来说效果很好,因为我 return 我的 plots/tables 作为主控制台中的列表。
但是,我无法在 Shiny 应用程序中执行它。我无法提供 API 信息,但出于所有意图和目的,这里是一个使用 mpg
数据集的可复制示例。
下面是一个使用动作按钮生成的绘图示例,没有使用重复循环。每次单击操作按钮时,图形将更新为当前系统时间:
以及生成此代码的代码:-
library(shiny)
library(ggplot2)
ui<-fluidPage(
titlePanel('Minimal example'),
tabsetPanel(
tabPanel("Example",
#summary
sidebarPanel(width = 4,
h5("The default interval for the analysis refresh is 5 minutes. If you wish to change this, please do so in the box below:"),
numericInput("intervaltime","Input refresh interval:",5),
br(),
h5("Press 'Run Analysis' button below to start automated analysis"),
actionButton("automatedanalysis", "Run Analysis")),
mainPanel(
h4("An example plot"),
plotOutput("example_plot", width = "100%"),
h4("Some text with updated system time"),
textOutput("example_text")
)
)))
server<-function(input,output,session){
observeEvent(input$automatedanalysis,{
#interval=input$intervaltime*60
#repeat{
currenttime<-Sys.time()
p<-ggplot(mpg, aes(displ, hwy, colour = class)) +
geom_point()+ggtitle(paste0("graph made at: ",currenttime))# adds on the current time
output$example_plot<-renderPlot({
return(p)
})
output$example_text<-renderText({
print(paste0("The current system time is: ", Sys.time())) #a check to know that it is working
})
#Sys.sleep(interval)
#}
})
}
shinyApp(ui, server)
然而,当我使用 UI 中的数字输入来切换间隔计时器时,我将重复循环投入使用,它不再起作用。这是非工作代码:-
ui<-fluidPage(
titlePanel('Minimal example'),
tabsetPanel(
tabPanel("Example",
#summary
sidebarPanel(width = 4,
h5("The default interval for the analysis refresh is 5 minutes. If you wish to change this, please do so in the box below:"),
numericInput("intervaltime","Input refresh interval:",5),
br(),
h5("Press 'Run Analysis' button below to start automated analysis"),
actionButton("automatedanalysis", "Run Analysis")),
mainPanel(
h4("An example plot"),
plotOutput("example_plot", width = "100%"),
h4("Some text with updated system time"),
textOutput("example_text")
)
)))
server<-function(input,output,session){
observeEvent(input$automatedanalysis,{
interval=input$intervaltime*60
repeat{
currenttime<-Sys.time()
p<-ggplot(mpg, aes(displ, hwy, colour = class)) +
geom_point()+ggtitle(paste0("graph made at: ",currenttime))# adds on the current time
output$example_plot<-renderPlot({
return(p)
})
output$example_text<-renderText({
print(paste0("The current system time is: ", Sys.time())) #a check to know that it is working
})
Sys.sleep(interval)
}
})
}
shinyApp(ui, server)
没有图表或文本输出出现。
再一次,这在 Shiny App 之外工作正常,但我需要它作为我正在开发的 Shiny App 中的一个功能。
总而言之,我怎样才能让它工作,以便在单击操作按钮时,在间隔期结束后刷新分析?
您应该看看 invalidateLater
或 reactiveTimer
函数。
我在以下示例中使用 invalidateLater
(注意:该函数将毫秒作为第一个参数)。
你也不应该在观察者中放置任何输出,创建一个 reactiveVal
/ reactiveValues
对象并在每个新的时间间隔填充它。然后您可以在应用程序的任何地方使用该对象。
我还将 observeEvent
更改为正常的 observe
,否则它只会在单击按钮时触发。现在,观察者触发,当单击 Button 时,间隔滑块发生变化,并且间隔已经过去。
library(shiny)
library(ggplot2)
ui<-fluidPage(
titlePanel('Minimal example'),
tabsetPanel(
tabPanel("Example",
sidebarPanel(width = 4,
h5("The default interval for the analysis refresh is 5 minutes. If you wish to change this, please do so in the box below:"),
numericInput("intervaltime","Input refresh interval:",5),
br(),
h5("Press 'Run Analysis' button below to start automated analysis"),
actionButton("automatedanalysis", "Run Analysis")),
mainPanel(
h4("An example plot"),
plotOutput("example_plot", width = "100%"),
h4("Some text with updated system time"),
textOutput("example_text")
)
)))
server<-function(input,output,session){
rv <- reactiveVal(NULL)
observe({
interval = input$intervaltime*1000
invalidateLater(interval, session)
req(input$automatedanalysis)
print("Fill ReactiveVal")
mpg$hwy <- mpg$hwy * runif(nrow(mpg))
rv(mpg)
})
output$example_plot<-renderPlot({
req(rv())
currenttime<-Sys.time()
print("Plot Code")
ggplot(rv(), aes(displ, hwy, colour = class)) +
geom_point()+ggtitle(paste0("graph made at: ",currenttime))
})
output$example_text<-renderText({
print(paste0("The current system time is: ", Sys.time())) #a check to know that it is working
})
}
shinyApp(ui, server)