Я делаю приложение, которое имеет пользовательский ввод (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)