无法获取Shiny

时间:2019-12-14 20:04:54

标签: r shiny

我对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")
        )
    )
)

1 个答案:

答案 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()})  

    }