【问题标题】:Plotting graphs in Shiny R; using a repeat loop to plot data for automated analysis在 Shiny R 中绘制图形;使用重复循环绘制数据以进行自动分析
【发布时间】:2021-02-16 10:45:04
【问题描述】:

编辑

我正在构建一个闪亮的应用程序,其中一个组件将包括自动数据分析。我的主要用途是访问 API 以收集数据并对其进行后续分析。此操作发生在 repeat 循环内,延迟 5 分钟(尽管这可以由应用程序的用户指定)。延迟结束后,再次访问 API 并重新开始该过程。当我在主控制台中将我的绘图/表格作为列表返回时,这对我来说非常有用。

但是,我无法在 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 中的一项功能。

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

【问题讨论】:

  • 嗨@Robin。如果没有完整的可重复脚本,就很难提供帮助。虽然您说 Shiny App 使用了一些敏感内容,但也许您可以生成一些虚拟数据来处理?我不确定这一点,但由于您在observeEvent 调用中使用repeat,并且在其中创建的对象是短暂的,仅在退出时显示。我认为您的repeat 电话永远不会结束,那么“observeEvent”永远不会完成无法打印您的情节。尝试在observeEvent 之外使用reactiveValues
  • 嗨@BaltazarGonzálezChávez,我同意很难提供帮助,通常我会尝试提供一个reprex来提供帮助,但在这种情况下并不可行。这个想法是操作按钮automatedanalysis 启动自动分析,然后启动repeat 循环过程。你所说的与observeEvent 相关是有道理的,但是,当我将它包装在reactiveValues 中时,我得到“reactiveValues 中的错误({:必须命名传递给 reactiveValues() 的所有参数”。知道为什么是?
  • 一个更简单的问题是:有没有合适的方法在闪亮的应用程序中使用重复循环来重现 UI 中的新图?有没有这样的例子(从我的搜索到目前为止,我还没有想出太多)?如果我能让这个工作,那么我可能可以从那里提出我的问题。
  • 嗨@BaltazarGonzálezChávez,我已经更新了这个问题,使其更加友好和可重复。我还添加了赏金。所以随意看看,看看你能不能解决它。谢谢!

标签: r plot shiny repeat shinydashboard


【解决方案1】:

您应该看看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)

【讨论】:

  • 嗨@SeGa,非常感谢你看这个。我将尝试在这里使用我的实际数据集来扩充它,我将在几个小时内确认它是否有效:)
  • 这很好用,我做了一些小的调整,但只针对我自己的数据。谢谢!
  • 嗨@SeGa,再次感谢您的解决方案,它非常有效!我想知道我是否可以再问一个问题。由于此代码中的分析是自动化的,我正在考虑添加一个额外的actionButton,它只会停止自动分析。我似乎无法在网上找到任何相关的例子,我想知道你是否可以提出一些建议?只有在不太麻烦的情况下才会非常感激:)
  • 您可以使用相同的 actionButton 并使用模 2 检查按钮是否处于活动状态。 -> 将req(input$automatedanalysis %% 2 != 0) 放在invalidateLater 部分之前应该可以工作。
  • 嗨 SeGa,抱歉,我花了很长时间才回复。太好了,非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-16
  • 2016-01-08
  • 2016-09-29
  • 2019-06-15
  • 2021-10-27
  • 2019-03-28
相关资源
最近更新 更多