R Shiny не работает для прогнозирования модели регрессии временных рядов - PullRequest
0 голосов
/ 28 марта 2020

Я делаю приложение, которое имеет пользовательский ввод (selectInput) для нескольких фреймов данных . Пользователь должен получить диаграмму фактических данных и их интервал прогнозирования (30%, 50%, 70%) для модели регрессии временных рядов, когда выбран ввод данных, как показано ниже. Dygraph с PI

Теперь это прекрасно работает в R, но как только я попытался реализовать его в R Shiny, оно не работает, когда отображается сообщение об ошибке Warning: Error in <-: object is not a matrix. Я приложил сокращенную версию своего кода, чтобы показать, что все остальное в приложении работает нормально, включая диаграмму для прогнозирования модели ARIMA и итоговый результат модели временной регрессии. Проблема начинается со строки graph<-reactive({, где output$PLOT3 в Tab 3 - это желаемый результат работы графов. Я перепробовал все, более конкретно, я попытался изменить положение кода, поместив их в renderDygraph, а затем вне renderDygraph и т. Д. c .. Я извиняюсь за то, что не смог прикрепить данные, которые я использую, вместе с моей проблемой, так как я не допускается по причине конфиденциальности данных. Любая помощь будет принята с благодарностью! Большое спасибо.

ui <- fluidPage(
  headerPanel(h1("Time Series Analysis 2020")),
  headerPanel(""),
  sidebarPanel(
    div(style = "font-size:85%;", uiOutput(outputId = "DATA")), width = 2),
  br(),
  br(),
  mainPanel(
    tabsetPanel(
      tabPanel("Tab 1",
               br(),
               div(style = "font-size:85%;", 
                            DT::dataTableOutput(outputId = "TABLE", width = "100%" ), 
               br(),
               fluidRow(
                 div(column(8, offset = 2, align = "center", style = "margin-bottom:50px;",
                            dygraphOutput(outputId = "PLOT", width = "150%"))))),
      tabPanel("Tab 2",
               h3("ARIMA model"),
               verbatimTextOutput(outputId = "ARIMA"),
               h3("ARIMA Forecast"),
               div(style = "margin-bottom:50px;",
                   dygraphOutput(outputId = "PLOT2", width = "100%"))),
      tabPanel("Tab 3",
               h3("Regression model summary"),
               verbatimTextOutput(outputId = "REGRESSION"),
               h3("Regression forecast dygraph"),
               div(style = "margin-bottom:50px;",
                   dygraphOutput(outputId = "PLOT3", width = "100%")))
    )
  )
)

server <- function(input, output){
  output$DATA <- renderUI({
    selectInput(inputId = "dataset",
                label = "please choose a data set", width = "200px",
                selected = NULL, multiple = FALSE, 
                choices = list())
  })
  # TAB 1
  output$TABLE <-  DT::renderDataTable(
    DT::datatable(df(), rownames = FALSE, filter = 'top', escape = FALSE,
                  style = 'bootstrap', 
                  class = 'table table-striped table-bordered dt-responsive nowrap')
    )
  df <- reactive({
    if(is.null(input$dataset)){return()}
    get(input$dataset)
  })
  output$PLOT <- renderDygraph({
    if(is.null(input$dataset)){return()}
    df <- get(input$dataset)
    tsdata <- ts(df$FixedCounts, frequency = 12, 
                 start = c(min(df$year), min(df[df$year == min(df$year), "month"])), 
                 end = c(max(df$year), max(df[df$year == max(df$year), "month"])))
    dygraph(tsdata, main = paste("Time series plot of", isolate(input$dataset))) %>%
      dySeries("V1", label = "Total") %>%
      dyAxis("y", label = "Monthly Vistors (thousands)") %>%
      dyHighlight(highlightCircleSize = 5,
                  highlightSeriesOpts = list(strokeWidth = 2))
  })
  # TAB 2
  fit <- reactive({
    if(is.null(input$dataset)){return()}
    df <- get(input$dataset)
    tsdata <- ts(df$FixedCounts, frequency = 12, 
                 start = c(min(df$year), min(df[df$year == min(df$year), "month"])), 
                 end = c(max(df$year), max(df[df$year == max(df$year), "month"])))
    train <- window(tsdata, 
                    start = c(start(time(tsdata))[1], match(month.abb[cycle(tsdata)][1], month.abb)), 
                    end = c(floor(time(tsdata)[floor(length(tsdata)*0.8)]),
                            match(month.abb[cycle(tsdata)][floor(length(tsdata)*0.8)], month.abb)))
    fit <- auto.arima(train, stepwise = FALSE, approximation = FALSE) 
  })
  output$ARIMA <- renderPrint({
    summary(fit())
  })
  output$PLOT2 <- renderDygraph({
    ARIMA.mean <- forecast(fit(), level = c(30,50,70), h = 36, biasadj = TRUE)
    graph <- cbind(actuals = ARIMA.mean$x, pointfc_mean = ARIMA.mean$mean,
                   lower_70 = ARIMA.mean$lower[,"70%"], upper_70 = ARIMA.mean$upper[,"70%"],
                   lower_50 = ARIMA.mean$lower[,"50%"], upper_50 = ARIMA.mean$upper[,"50%"],
                   lower_30 = ARIMA.mean$lower[,"30%"], upper_30 = ARIMA.mean$upper[,"30%"])
    dygraph(graph, main = ARIMA.mean$method, ylab = "Monthly Visitors") %>%
      dySeries(name = "actuals") %>%
      dySeries(name = "pointfc_mean", label = "forecast") %>%
      dySeries(name = c("lower_30", "pointfc_mean", "upper_30"), label = "30% PI") %>%
      dySeries(name = c("lower_50", "pointfc_mean", "upper_50"), label = "50% PI") %>%
      dySeries(name = c("lower_70", "pointfc_mean", "upper_70"), label = "70% PI") 
    })
  # TAB 3
  fitted <- reactive({
    if(is.null(input$dataset)){return()}
    df <- get(input$dataset)
    tsdata <- ts(df$FixedCounts, frequency = 12, 
                 start = c(min(df$year), min(df[df$year == min(df$year), "month"])), 
                 end = c(max(df$year), max(df[df$year == max(df$year), "month"])))
    train <- window(tsdata, 
                    start = c(start(time(tsdata))[1], match(month.abb[cycle(tsdata)][1], month.abb)), 
                    end = c(floor(time(tsdata)[floor(length(tsdata)*0.8)]),
                            match(month.abb[cycle(tsdata)][floor(length(tsdata)*0.8)], month.abb)))
    fit.train <- tslm(train ~ trend + relevel(season, ref = which.min(tapply(train, cycle(train, FUN = sum)))))
  })
  output$REGRESSION <- renderPrint({
    fitted.model <- fitted()
    names(fitted.model$coefficients)[3:13] <- paste("month", substr(names(fitted.model$coefficients)[3:13],73,74))
    summary(fitted.model)
  })
  graph <- reactive({
    # get the selected data frame
    if(is.null(input$dataset)){return()}
    df <- get(input$dataset)
    # convert the selected data frame into a ts object
    tsdata <- ts(df$FixedCounts, frequency = 12, 
                 start = c(min(df$year), min(df[df$year == min(df$year), "month"])), 
                 end = c(max(df$year), max(df[df$year == max(df$year), "month"])))
    # split the ts object into a training set and a test set (only training set is shown here)
    train <- window(tsdata, 
                    start = c(start(time(tsdata))[1], match(month.abb[cycle(tsdata)][1], month.abb)), 
                    end = c(floor(time(tsdata)[floor(length(tsdata)*0.8)]),
                            match(month.abb[cycle(tsdata)][floor(length(tsdata)*0.8)], month.abb)))
    # fit the ts regression model using the training set
    fit.train <- tslm(train ~ trend + relevel(season, ref = which.min(tapply(train, cycle(train, FUN = sum)))))
    # have to use the forecast function for the 3 different P.I separately bc levels = 
    # c(30,50,70) doesn't work
    fit.30 <- forecast(fit.train, h = 36, level = 30, biasadj = TRUE)
    fit.50 <- forecast(fit.train, h = 36, level = 50, biasadj = TRUE)
    fit.70 <- forecast(fit.train, h = 36, level = 70, biasadj = TRUE)
    graph2 <- cbind(actuals = fit.30$x, pointfc_mean = fit.30$mean,
                    lower_70 = fit.70$lower, upper_70 = fit.70$upper,
                    lower_50 = fit.50$lower, upper_50 = fit.50$upper,
                    lower_30 = fit.30$lower, upper_30 = fit.30$upper)
  })
  output$PLOT3 <- renderDygraph({
    graph <- graph()
    dygraph(graph, ylab = "Monthly Visitors") %>%
      dySeries(name = "actuals") %>%
      dySeries(name = "pointfc_mean", label = "forecast") %>%
      dySeries(name = c("lower_30", "pointfc_mean", "upper_30"), label = "30% PI") %>%
      dySeries(name = c("lower_50", "pointfc_mean", "upper_50"), label = "50% PI") %>%
      dySeries(name = c("lower_70", "pointfc_mean", "upper_70"), label = "70% PI")
  })
}

shinyApp(ui = ui, server = server)
...