使用动态dateRange按动态selectInput

时间:2018-04-23 12:52:17

标签: r shiny aggregate shinydashboard reactive

我正在开发基于以下示例数据框的shinydashboard:

Date     Year Month Week Wday Day Time  ActiveEnergy
2/1/2009 2009 2     5    Sun  1    0    55.36111
3/1/2009 2009 3     9    Sun  1    0    9.334444
4/1/2007 2007 4     14   Sun  1    0    41.27667
6/1/2008 2008 6     22   Sun  1    0    32.89833
7/1/2007 2007 7     27   Sun  1    0    27.11667
8/1/2010 2010 8     31   Sun  1    0    4.871111

在sidebarMenu上,在子菜单" Historic"下,我想在用户选择的时间范围内显示消耗的ActiveEnergy的 barplot (ggplot)。这是通过在sidebarMenu中包含的日历(" dateRange")中选择dateRangeInput(开始和结束日期)来完成的。

反过来,我希望条形图的 x轴选定的时间范围,也是根据"选择时间动态选择的频率聚合的间隔" selectinput。

为此,我在服务器中创建了frequency变量,该变量将所选的input$TimeInterval转换为" by"变量我想在"聚合"中使用功能(例如"每周" =" Wday")。

但是,我无法将反应性input$dateRangeinput$TimeInterval和聚合函数组合在一起。

关于如何正确编写此级联过滤的任何想法?

以下是我的代码供您参考:

server <- function(input, output) {

  frequency <- observe({
    ifelse(input$TimeInterval=="Daily", "Hour",
           ifelse(input$TimeInterval=="Weekly", "Week",
                  ifelse(input$TimeInterval=="Monthly", "Month",
                         ifelse(input$TimeInterval=="Yearly", "Date"))))

  })

  filteredData <- reactive({
    data %>% filter(Date>=input$dateRange[1]  & Date<=input$dateRange[2])%>%
      select(frequency(), ActiveEnergy)
  })

  df<-reactive({
    freq<-paste(frequency())
    aggregate(filteredData(), filteredData()[[freq]] , FUN=mean, na.rm=TRUE)
  })

  output$plot1 <- renderPlot({
    ggplot(df(), aes(x=frequency(), y=ActiveEnergy)) +   geom_bar(stat = "identity", fill="steelblue")
  })
}

shinyApp(ui, server)

1 个答案:

答案 0 :(得分:0)

你不能称observer像被动反应一样,它不是为此而设计的,因为它产生副作用而不是产生反应数据集。因此,您的频率应该是reactive,您可以在应用中的其他地方调用。

您也不需要2个反应来生成过滤/聚合数据,您可以将其全部合并到一起,除非您在不同的过程中需要两个不同的数据集。

最后,正如@MLavoie已经说过,您的aes应该更改为aes_string,因为频率将是一个字符值,而aes无法正确解释。它只会显示1个小时。

总结你得到:

library(shiny)
library(ggplot2)
library(dplyr)

DateSeq = seq(as.Date("2012-1-1"), as.Date("2018-1-1"), "month")
data <- data.frame(
  ID = 1:length(DateSeq),
  Date = DateSeq,
  Month = sample(1:12, length(DateSeq), T),
  Week = sample(1:10, length(DateSeq), T),
  Wday = sample("Sun", length(DateSeq), T),
  Day = sample(1:10, length(DateSeq), T),
  ActiveEnergy = runif(length(DateSeq), min = 2, 7000)
)




ui <- fluidPage(
  selectInput("TimeInterval", label = "time", choices = c("Daily", "Weekly", "Monthly", "Yearly")),
  dateRangeInput("dateRange", "Date Select", format = "yyyy-mm-dd", start=min(DateSeq), end=max(DateSeq)),
  plotOutput("plot1")
)



server <- function(input, output) {

  frequency <- reactive({
    ifelse(input$TimeInterval=="Daily", "Day",
           ifelse(input$TimeInterval=="Weekly", "Week",
                  ifelse(input$TimeInterval=="Monthly", "Month",
                         ifelse(input$TimeInterval=="Yearly", "Date"))))
  })

  df <- reactive({
    data %>% 
      filter(Date >= input$dateRange[1]  & Date <= input$dateRange[2]) %>%
      group_by_(frequency()) %>%
      summarise(mean_active = mean(ActiveEnergy))
  })

  output$plot1 <- renderPlot({
    ggplot(data = df(), aes_string(x = frequency(), y = "mean_active", 
                                   group = factor(frequency()))) +
      geom_bar(aes_string(frequency(), "mean_active"), 
               stat = "identity", fill="steelblue")
  })
}

shinyApp(ui, server)