Search code examples
shinyrstudiorun-app

RStudio-Shiny code works line-by-line (Ctrl+Enter), but not with the "Run App" button


in RStudio the below Shiny code works fine if I run it using Ctrl+Enter, line-by-line. However, if I run the whole code using the "Run App" button it generates this error:

Error in ts(x) : 'ts' object must have one or more observations

I think it is due to "lambda" parameter but I cannot see why. Any help is appreciated.

The link for "data.csv" is https://www.dropbox.com/s/p1bhacdg8j1qx42/data.csv?dl=0

====================================

library(shiny)
library(shinydashboard)
library(plotly)
library(forecast)

df <- read.csv("data.csv")
demand <- ts(df$demand, start = c(1995, 1), frequency = 12)

lbd <- BoxCox.lambda(demand, lower=-5, upper=5)
m <- ar(BoxCox(demand,lambda=lbd))
fit_BC <- forecast(m, h=12, lambda=lbd)

ui <- dashboardPage(
  dashboardHeader(title = "Plot"),
  dashboardSidebar(disable = TRUE),
  dashboardBody(fluidRow(column(width = 12, box(plotlyOutput("forecast_plots"),width = NULL))))
)

server <- function(input, output) {
  output$forecast_plots <- renderPlotly({
    autoplot(fit_BC)
  })
}

shinyApp(ui, server)

==================================


Solution

  • autoplot() returns ggplot object. But your output$forecast_plots requires plotly object(with plotlyOutput() function).

    Working code is like the following:

    ui <- dashboardPage(
        dashboardHeader(title = "Plot"),
        dashboardSidebar(disable = TRUE),
        dashboardBody(fluidRow(column(width = 12, box(plotOutput("forecast_plots"),width = NULL))))
    )
    
    server <- function(input, output) {
        output$forecast_plots <- renderPlot({
            autoplot(fit_BC)
        })
    }
    

    ggplot objects can be easily converted with ggplotly function, but unfortunately converted plotly autoplot graph loses the forecasting region. You can verify it like:

    ui <- dashboardPage(
        dashboardHeader(title = "Plot"),
        dashboardSidebar(disable = TRUE),
        dashboardBody(fluidRow(column(width = 12, box(plotlyOutput("forecast_plots"),width = NULL))))
    )
    
    server <- function(input, output) {
        output$forecast_plots <- renderPlotly({
            ggplotly(autoplot(fit_BC))
        })
    }
    

    Add

    I found autoplotly library.https://terrytangyuan.github.io/2018/02/12/autoplotly-intro/

    autoplotly() function can convert autoplot object to plotly object which is roughly correct.

    library(shiny)
    library(shinydashboard)
    library(plotly)
    library(forecast)
    library(autoplotly)
    
    df <- read.csv("c:/Users/010170283/Downloads/data.csv")
    demand <- ts(df$demand, start = c(1995, 1), frequency = 12)
    
    lbd <- BoxCox.lambda(demand, lower=-5, upper=5)
    m <- ar(BoxCox(demand,lambda=lbd))
    fit_BC <- forecast(m, h=12, lambda=lbd)
    
    ui <- dashboardPage(
        dashboardHeader(title = "Plot"),
        dashboardSidebar(disable = TRUE),
        dashboardBody(fluidRow(column(width = 12, box(plotlyOutput("forecast_plots"),width = NULL))))
    )
    
    server <- function(input, output) {
        output$forecast_plots <- renderPlotly({
            autoplotly(autoplot(fit_BC))
        })
    }
    
    shinyApp(ui, server)
    

    The forecast region can be seen with it, and hi/lo 80 % edge values are presented with mouse hover event.

    enter image description here