我对Shiny还是很陌生,并且正在基于用户输入的基础数据修改生成具有VAR模型的应用程序。当我没有在全局环境中预加载任何数据时,Shiny在启动时崩溃(我尝试在本地和外部托管数据,但仍然获得相同的结果)。
我认为这与我指定反应式数据帧的方式有关,因为我可以在简单的R脚本(即嵌套在observeEvent(input$go,{
中的所有代码)中运行代码。启动后,出现以下错误:
警告:ts中的错误:“ ts”对象必须具有一个或多个观察结果
如果我在R的全局环境中有数据,则在我按下操作按钮时,它将使用本地生成的图/数据进行填充,这是合理的,因为它嵌套在observeEvent
下。它不会根据用户输入(尤其是预测)进行更新。
如果我的全局环境中没有数据,而我正在链接到硬盘驱动器或URL,则一旦按下操作按钮,屏幕就会变灰,并且根本不会更新。
我试图通过将四个用户输入标量应用于combined_df
中的四个变量来修改190x7数据帧combined_df
。然后,我尝试使用先前估计的线性回归来估算temp
的过去值(combined_df
中的变量之一)。先前估计的关系的系数存储在coef
中。类似地,输出应为190x7数据帧,然后我将其用于构建时间序列并重新估计VAR模型。
我认为我的问题与为数据框的子集指定函数有关,但是我不确定如何继续。
我在下面发布了我的服务器代码:
server <- function(input, output, session) {
rv = reactiveValues(df_data = NULL)
observeEvent(input$go,{
isolate({rv$df_data <- combine_df})
rv$df_data$co2 <- combine_df$co2 * as.numeric(input$slider1)/100
rv$df_data$sf6 <- combine_df$sf6 * as.numeric(input$slider2)/100
rv$df_data$n2o <- combine_df$n2o * as.numeric(input$slider3)/100
rv$df_data$ch4 <- combine_df$ch4 * as.numeric(input$slider4)/100
rv$df_data$temp <- as.numeric(as.matrix(combine_df[3:6]) %*% as.matrix(coef$'fit$coefficients'[2:5]) - 97.05746141)})
timeseries <- reactive({
tsco2 <-ts(rv$df_data[, c('co2')], start=c(1997, 7),end=c(2012, 1),frequency = 12)
tssf6 <-ts(rv$df_data[, c('sf6')], start=c(1997, 7),end=c(2012, 1),frequency = 12)
tsn2o <-ts(rv$df_data[, c('n2o')], start=c(1997, 7),end=c(2012, 1),frequency = 12)
tsch4 <-ts(rv$df_data[, c('ch4')], start=c(1997, 7),end=c(2012, 1),frequency = 12)
trend <-ts(rv$df_data[, c('temp')], start=c(1997, 7),end=c(2012, 1),frequency = 12)
multiplets <- ts_c(trend, tsch4, tsco2, tsn2o, tssf6)
#multiplets <- window(multiplets, start=c(1997, 7), end=c(2012,1))
})
VARmodel <- reactive ({VAR(timeseries(), p=3, type = "both")})
fcast_for_plot <- reactive ({forecast(VARmodel(), h=50)})
extractresults <- reactive({
#fcastv1 <- forecast(VARmodel(), h=100)
results <- fcast_for_plot()$model$varresult
fcast_trend <- forecast(results$trend$model$y)
fcasttrend <- as.data.frame(fcast_trend$mean)
})
repeatableplot <- reactive ({plot(fcast_for_plot(), xlab="Year")})
output$varplot <- renderPlot({repeatableplot()})
output$predtable <- renderTable({
head(extractresults())})
}
编辑:ui代码在下面。
ui <- fluidPage(
pageWithSidebar(
headerPanel("Greenhouse gas concentration and impact on Canadian Ground Temperature"),
sidebarPanel(
# Slider input for co2 change
sliderInput("slider1", "Carbon dioxide (CO2) concentration percent change:",
min = 10, max = 200, value = 100),
# Slider input for sf6 change
sliderInput("slider2", "Sulfur hexafluoride (SF6) concentration percent change:",
min = 10, max = 200, value = 100),
# Slider input for N2O change
sliderInput("slider3", "Nitrous oxide (N2O) concentration percent change:",
min = 10, max = 200, value = 100),
# Slider input for ch4 change
sliderInput("slider4", "Methane (CH4) concentration percent change:",
min = 10, max = 200, value = 100),
actionButton("go","Predict")
),
mainPanel(
plotOutput("varplot"),
plotOutput("tempplot"),
tableOutput("predtable")
)
)
)
答案 0 :(得分:0)
我发现了问题。解决方案是:
1)指定时间序列的全局函数
#specifying the function that will turn our data into a time series once it's adjusted, to be applied to rv$df_data (a)
timeseries <- function(x) {
tsco2 <-ts(x[, c('co2')], start=c(1997, 7),end=c(2012, 1),frequency = 12)
tssf6 <-ts(x[, c('sf6')], start=c(1997, 7),end=c(2012, 1),frequency = 12)
tsn2o <-ts(x[, c('n2o')], start=c(1997, 7),end=c(2012, 1),frequency = 12)
tsch4 <-ts(x[, c('ch4')], start=c(1997, 7),end=c(2012, 1),frequency = 12)
temptrend <-ts(x[, c('temp')], start=c(1997, 7),end=c(2012, 1),frequency = 12)
assign("temptrend",temptrend,envir=.GlobalEnv)
multiplets <- ts_c(temptrend, tsch4, tsco2, tsn2o, tssf6)
multiplets <- window(multiplets, start=c(1997, 7), end=c(2012,1))
assign("multiplets",multiplets,envir=.GlobalEnv)
VARobject <- VAR(multiplets, p=3, type = "both")
assign("VARobject",VARobject,envir=.GlobalEnv)
fcast_for_plot <- forecast::forecast(VARobject, h=50)
assign("fcast_for_plot",fcast_for_plot,envir=.GlobalEnv)
return(fcast_for_plot)
}
timeseries2 <- function(x) {
tsnewtemp <- ts(x[, c('temp')], start=c(1997,7), end=c(2012,1),frequency=12)
newtempforecast <- predict(tsnewtemp)
assign("newtempforecast",newtempforecast,envir=.GlobalEnv) # put it in the global env
return(newtempforecast)
}
2)为反应值创建一个空数据集 3)用数据框填充无功值 4)根据用户输入创建反应变量 5)用户点击“提交”后,重新计算反应变量的列
请参阅下面的最终服务器代码,其中包含解决方案步骤2)-5)。
另一个有趣的事实是:我认为vars包不接受新的数据集。如果我对varest对象VARobject
进行预测或预测,它将返回用于预测的空向量。
server <- function(input, output, session) {
#specifying a reactive dataset that is currently empty, but will be populated by our dataframe
rv = reactiveValues(df_data = NULL)
rv$df_data = combine_df
#Creating reactive variables based on user inputs, as percentages
inp1 <- reactive ({(as.numeric(input$slider1))/100})
inp2 <- reactive ({(as.numeric(input$slider2))/100})
inp3 <- reactive ({(as.numeric(input$slider3))/100})
inp4 <- reactive ({(as.numeric(input$slider4))/100})
#Upon hitting predict, we recalculate the columns of our reactive data
observeEvent(input$go, {
isolate({
rv$df_data[,3] <- (combine_df[,3] * inp1())
rv$df_data[,6] <- (combine_df[,6] * inp2())
rv$df_data[,4] <- (combine_df[,4] * inp3())
rv$df_data[,5] <- (combine_df[,5] * inp4())
rv$df_data[,2] <- (as.numeric(as.matrix(rv$df_data[3:6]) %*% as.matrix(coef$'fit.coefficients'[2:5]) - 97.05746141))
assign("rv$df_data",rv$df_data,envir=.GlobalEnv)
})
})
a <- reactive ({timeseries(rv$df_data)})
b <- reactive ({timeseries2(rv$df_data)})
repeatableplot <- reactive ({plot(a(), main="Initial forecast and updated values", xlab="Year")})
repeatableplot2 <- reactive ({plot(b(), main="Estimates of Temperature Updated Trend", xlab="Year")})
repeatabletable <- reactive ({b()})
output$varplot <- renderPlot({repeatableplot()})
output$tempplot <- renderPlot({repeatableplot2()})
output$predtable <- renderTable({repeatabletable()})
}