闪亮:根据图谱的RangeSelector计算总和

时间:2019-04-23 11:02:12

标签: shiny shinydashboard dygraphs cumsum

我正在构建一个闪亮的应用程序,在这里我想绘制一个数据集,其中一个变量是另一个变量的累加和。每次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)

更新

我修改了@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)

2 个答案:

答案 0 :(得分:1)

更新后的代码存在问题,因为您没有保留日期信息。同样,一旦您开始基于图本身的变化(递归)来绘制图,它就会有些棘手。您必须确保重新渲染图不会再次触发渲染,否则您将陷入循环。这就是为什么我将keepDateWindow设置为TRUE的原因。除此之外,您不希望在滑块第一次更改后立即重新绘制图,这就是我对子数据进行去抖动的原因。

尽管如此,使用刻度图仍然存在问题,当您将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()

答案 1 :(得分: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