Search code examples
rshinyplotlytidyverseflexdashboard

shiny plotly failed to plot the series line plot actively after applying the filter


I have a dafarame which looks like this:

df <- data.frame(Date = rev(seq(as.Date("2020-01-01"),
                                as.Date("2021-08-15"),"day")),
                 Var1 = sample(10:100, 593, replace = TRUE), 
                 Var2 = sample(10:100, 593, replace = TRUE), 
                 Var3 = sample(10:100, 593, replace = TRUE), 
                 Var4 = sample(10:100, 593, replace = TRUE)
)

df$CovidPeriod <- ifelse((df$Date>=as.Date("2020-03-01", format="%Y-%m-%d") & 
                            df$Date<=as.Date("2020-09-30", format="%Y-%m-%d")), 
                          "Covid", "NonCovid")

Now what I wanted to do is to create plotly time series chart in shiny flexdashboard.

I tried this:

library(tidyverse)
library(plotly)
library(flexdashboard)
library(shiny)

selectInput("Series1", label = "Select Series:", choices = c("Select", "Var1", "Var2", "Var3", "Var4",), selected="Select")
 
checkboxInput("covid", "Exclude covid period?", FALSE)
output$value <- renderText({ input$covid })

output$df2 <- reactive({
    if(input$covid == 'Covid'){ 
    filter(df, CovidPeriod == "NonCovid")
  }
})


renderPlotly({
  plot_ly(df2(), x = ~df2$Date, y = ~df2[[input$Series1]], type='scatter', mode = 'lines', name = 'Actual',
          line=list(color='rgb(56, 98, 249)', width=4)
          ) %>%
      layout(title = "Series",
             xaxis = list(title = "Year"),
             yaxis = list(title = "Series excluding Covid time")
             )
})

I got errors:

  Warning: Error in df2: could not find function "df2"
  106: is.data.frame
  105: plot_ly
  102: renderPlotly [<text>#38]
  101: func
   98: shinyRenderWidget
   97: func
   84: renderFunc
   83: output$out7e4e6b71a6155385
    3: <Anonymous>
    1: rmarkdown::run

Could someone please help on how to line plot the series basis selected for filtering of covid period or entire series (without any filtering applied)?


Solution

  • I edited your code a little bit, you can easily apply with flexdashboard

    library(shiny)
    library(plotly)
    library(tidyverse)
    
    
    df <- data.frame(Date = rev(seq(as.Date("2020-01-01"),
                                    as.Date("2021-08-15"),"day")),
                     Var1 = sample(10:100, 593, replace = TRUE), 
                     Var2 = sample(10:100, 593, replace = TRUE), 
                     Var3 = sample(10:100, 593, replace = TRUE), 
                     Var4 = sample(10:100, 593, replace = TRUE)
    )
    
    df$CovidPeriod <- ifelse((df$Date>=as.Date("2020-03-01", format="%Y-%m-%d") & 
                                  df$Date<=as.Date("2020-09-30", format="%Y-%m-%d")), 
                             "Covid", "NonCovid")
    
    ui <- fluidPage(
        titlePanel("Old Faithful Geyser Data"),
        sidebarLayout(
            sidebarPanel(
                selectInput("Series1", label = "Select Series:", choices = c("Select", "Var1", "Var2", "Var3", "Var4"), selected="Var1"),
                checkboxInput("covid", "Exclude covid period?",value = F)
            ),
            mainPanel(
               plotlyOutput("outplot")
            )
        )
    )
    
    server <- function(input, output) {
    
        df2 <- reactive({
            
            newdf <- df
            if(input$covid){ 
                newdf <- filter(df, CovidPeriod == "NonCovid")
            }
            newdf
            
            
        })
        
        output$outplot <- renderPlotly({
            
            filtered_data <- df2()
            plot_ly(filtered_data, x = ~filtered_data$Date, y = ~filtered_data[[input$Series1]], type='scatter', mode = 'lines', name = 'Actual',
                    line=list(color='rgb(56, 98, 249)', width=4)
            ) %>%
                layout(title = "Series",
                       xaxis = list(title = "Year"),
                       yaxis = list(title = "Series excluding Covid time")
                )
        })
    }
    shinyApp(ui = ui, server = server)
    

    enter image description here

    Note that, you shouldn't call reactive objects directly. You had better assign them to a new object (which I did by "filtered data") with parentheses to work clear.