闪亮:根据dygraphs的RangeSelector计算cumsum

问题描述 投票:1回答:2

我正在构建一个闪亮的应用程序,我想绘制一个数据集,其中一个变量是另一个变量的累积和。每当dygraphs'dyRangeSelector的开始日期发生变化时,都需要重新计算后者。下面是没有cumsum计算的基本代码。注释掉的代码就是我尝试过的,没有成功。

library(shinydashboard)
library(stringr)
library(zoo)
library(dplyr)
library(dygraphs)

ui <-dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody(
    uiOutput("Ui1")
  )
)

server <- function(input, output, session) {


  output$Ui1 <- renderUI({

    # date range observer 

    # values <- reactiveValues()
    # 
    # observeEvent(input$plot1_date_window, {
    #   from <- as.Date(str_sub(input$plot1_date_window[[1]], 1, 10))
    # })

    ## dygraphs plot 
    output$plot1 <- renderDygraph({

      m_df <- data.frame(date=as.Date(zoo::as.yearmon(time(mdeaths))), Y=as.matrix(mdeaths))

      # input_data <- m_df %>% 
      #   filter(date >= values$from) %>% 
      #   mutate(cumY = cumsum(Y)) 

      input_xts <- xts(select(m_df, -date), 
                       order.by = m_df$date)
                       #select(input_data, -date),
                       #order.by = input_data$date)


      p <- dygraph(input_xts) %>% 
        dyRangeSelector()

      p  
    })

    ## outputs
    dygraphOutput('plot1')
  })


}

shinyApp(ui, server)

UPDATE

我修改了@Pork Chop的答案,能够在一张图上用其他指标绘制累积值,但我现在甚至都无法显示该图:

library(xts)
library(shiny)
library(shinydashboard)
library(dygraphs)

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody(
    dygraphOutput('plot1'),
    textOutput("cumsum1")
  )
)

server <- function(input, output, session) {

  m_df <- data.frame(date=as.Date(zoo::as.yearmon(time(mdeaths))), Y=as.matrix(mdeaths))
  subdata <- reactive({
    cumsum(m_df$Y[m_df$date >= as.Date(input$plot1_date_window[1]) & m_df$date <= as.Date(input$plot1_date_window[2])])
  })

  output$plot1 <- renderDygraph({
    req(input$plot1_date_window)
    input_xts <- xts(select(m_df, -date), order.by = m_df$date)
    subdata_xts <- xts(select(subdata(), - date), order.by = subdata()$date)
    final_xts <- cbind(input_xts, subdata_xts)

    dygraph(final_xts) %>% 
      dyRangeSelector()
  })

  output$cumsum1 <- renderText({
    req(input$plot1_date_window)
    subdata <- cumsum(m_df$Y[m_df$date >= as.Date(input$plot1_date_window[1]) & m_df$date <= as.Date(input$plot1_date_window[2])])
    subdata
  })

}

shinyApp(ui, server)
shiny shinydashboard dygraphs cumsum
2个回答
1
投票

您更新的代码的问题是,您没有保留日期信息。一旦你开始根据绘图本身的变化(递归)渲染绘图,它就会变得有点棘手。您必须确保重新渲染绘图不会再次触发渲染,否则您将最终处于循环中。这就是我设置retainDateWindow = TRUE的原因。除此之外,您不希望在第一次更改滑块后立即重新渲染绘图,这就是我去除子数据的原因。

尽管如此,使用dygraph仍然存在问题,当你将cumsum作为一个系列添加时,你的dyRangeSelector图会被改变(y所有系列的最大值)。请参阅以下代码:

library(xts)
library(shiny)
library(shinydashboard)
library(dygraphs)
library(dplyr)

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody(
    dygraphOutput('plot1')
  )
)

server <- function(input, output, session) {

  m_df <- data.frame(date=as.Date(zoo::as.yearmon(time(mdeaths))), Y=as.matrix(mdeaths))

  subdata <- reactive({
    if(!is.null(input$plot1_date_window)){
      subdata <- m_df[m_df$date >= as.Date(input$plot1_date_window[1]) & m_df$date <= as.Date(input$plot1_date_window[2]), ]
      subdata$cumsum <- cumsum(subdata$Y)
      subdata$Y <- NULL
    } else {
      subdata <- NULL
    }

    return(subdata)
  })

  subdata_d <- subdata %>% debounce(100)

  output$plot1 <- renderDygraph({
    input_xts <- xts(select(m_df, -date), order.by = m_df$date)
    if(is.null(subdata_d())){
      final_xts <- input_xts
    } else {

      subdata_xts <- xts(select(subdata_d(), - date), order.by = subdata_d()$date)
      final_xts <- cbind(input_xts, subdata_xts)
    }

    p <- dygraph(final_xts) %>% dySeries(name="Y") %>%
      dyRangeSelector(retainDateWindow = TRUE)

    if("cumsum" %in% names(final_xts)){
      p <- dySeries(p, name="cumsum", axis = "y2")
    }

    p
  })

}

shinyApp(ui, server)

就像@PorkChop提到的那样,我推荐这个场景的多个输出。此外,我建议看看library(plotly),它是event_data()


0
投票

这应该可以完成这项工作,我认为为仪表板提供单独的输出更为清晰

library(xts)
library(shiny)
library(shinydashboard)
library(dygraphs)

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody(
    dygraphOutput('plot1'),
    textOutput("cumsum1")
  )
)

server <- function(input, output, session) {

  m_df <- data.frame(date=as.Date(zoo::as.yearmon(time(mdeaths))), Y=as.matrix(mdeaths))

  output$plot1 <- renderDygraph({
    input_xts <- xts(select(m_df, -date), order.by = m_df$date)

    dygraph(input_xts) %>% 
      dyRangeSelector()
  })

  output$cumsum1 <- renderText({
    req(input$plot1_date_window)
    subdata <- cumsum(m_df$Y[m_df$date >= as.Date(input$plot1_date_window[1]) & m_df$date <= as.Date(input$plot1_date_window[2])])
    subdata
  })

}

shinyApp(ui, server)

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.