在 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 中的一个功能。

总而言之,我怎样才能让它工作,以便在单击操作按钮时,在间隔期结束后刷新分析?

您应该看看 invalidateLaterreactiveTimer 函数。

我在以下示例中使用 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)