R Shiny. Error in :: argument of length 0

rshiny

I have the following error appearing when running R Shiny:

    Listening on http://127.0.0.1:7473
    Warning: Error in :: argument of length 0
    Stack trace (innermost first):
    76: renderPlot [C:\Users\voroneci\Documents\Dissertation\Projecting Swaption Vol\Log Normal Vol Projector App - Using PR2/server.R#162]
    68: output$lognormal2
     1: shiny::runApp

App does run locally, however when deploying on shinyapps.io it greys out with the classic message of server being disconnected, I am assuming it is due to this error.

server.R:

    require(shiny,quietly = TRUE)
require(forecast,quietly = TRUE)
require(rsconnect,quietly = TRUE)
options(shiny.maxRequestSize=30*1024^2)

load("./PR2.RData")
load("./F1.RData")
load("./F2.RData")
load("./all_data_lognormal.RData")
load("./R.RData")
load("./sigma.RData")
load("./mu.RData")



shinyServer(function(input, output, session) {
    output$lognormal <- renderPlot({
      all_data              <- all_data[all_data$LogNormalVol>0,]
      all_data$LogNormalVol <- (log10(all_data$LogNormalVol)+1)/0.1

      if(is.null(input$run) |is.na(input$run)  ){
        return()
      }else{
      input$run  
      ahead  <- isolate(input$ahead)
      paths  <- isolate(input$paths)
      und_   <- isolate(input$Underlying)
      exp_   <- isolate(input$Expiry)
      str_   <- isolate(input$Strike)
      seed   <- isolate(input$seed)

      imp    <- subset(all_data,all_data$UND==und_)
      imp    <- subset(imp     ,imp$EXP==exp_)
      imp    <- subset(imp     ,imp$Strike==str_)
      imp    <- imp[!duplicated(imp$Date),]
      imp    <- imp$LogNormalVol/100


      set.seed(seed)

      estimate.I  <- ts(replicate(paths, simulate(model1.3, nsim=ahead, xreg = 1259+1:ahead ,future = TRUE)),start=1259+1)
      estimate.II <- ts(replicate(paths, simulate(model2.3, nsim=ahead, xreg = 1259+1:ahead ,future = TRUE)),start=1259+1)

      predicted.vol <-c() 

      for(i in 1:paths){
        projected.PCs          <- cbind(estimate.I[,i],estimate.II[,i])
        reconstructed.F        <- projected.PCs%*%t(R)[1:2,]
        reconstructed.F_scaled <- matrix(rep(mu,times=nrow(reconstructed.F)),byrow=TRUE,ncol=14) + reconstructed.F * matrix(rep(sigma,times=nrow(reconstructed.F)),byrow=TRUE,ncol=14)

        predict.df      <- data.frame(Date=c(1:ahead),
                                      LogNormalVol=rep(NA,times=length(c(1:ahead))),
                                      UND    = as.numeric(rep(und_,times=length(c(1:ahead)))), 
                                      EXP    = as.numeric(rep(exp_,times=length(c(1:ahead)))), 
                                      Strike = as.numeric(rep(str_,times=length(c(1:ahead)))),
                                      F1 =reconstructed.F_scaled[,1] ,
                                      F2 =reconstructed.F_scaled[,2] ,
                                      F3 =reconstructed.F_scaled[,3] ,
                                      F4 =reconstructed.F_scaled[,4] ,
                                      F5 =reconstructed.F_scaled[,5] ,
                                      F6 =reconstructed.F_scaled[,6] ,
                                      F7 =reconstructed.F_scaled[,7] ,
                                      F8 =reconstructed.F_scaled[,8] ,
                                      F9 =reconstructed.F_scaled[,9] ,
                                      F10=reconstructed.F_scaled[,10],
                                      F11=reconstructed.F_scaled[,11],
                                      F12=reconstructed.F_scaled[,12],
                                      F13=reconstructed.F_scaled[,13],
                                      F14=reconstructed.F_scaled[,14])

        predicted.vol2 <- predict(PR2,newdata=predict.df)
        predicted.vol  <- rbind(predicted.vol,predicted.vol2)
      }
      predicted.vol <-(predicted.vol+1)/0.1
      predicted.vol <- predicted.vol/100
      all       <- cbind(matrix(rep(imp,times=paths),nrow=paths,byrow=TRUE),predicted.vol)

      ylim      <- c(min(all),
                     max(all))


      for(i in 1:paths){
        if(i==1){
          if(length(imp)==0){
            plot(c(0,1),c(0,1),type="n", xlab="",ylab="", xaxt='n', yaxt='n')
            legend(0.15,0.6,"Data not available",cex=1.5)
          }else{
            plot(imp,type="l",xlim=c(0,(length(imp)+ahead)),ylab="Log-Normal Vol", xlab="Steps",cex.lab=0.8,lty=1,lwd=2,col="darkblue",ylim=ylim,
                 main="Zoom In Plot")
            #legend("topleft",c("Observed","Projected"),col=c("darkblue","darkgreen"),lty=1)

          }
        }
        lines(c((length(imp)+1):(length(imp)+ahead)),predicted.vol[i,],col=i,lty=i,lwd=1)
        lines(c(length(imp),length(imp)+1),c(imp[length(imp)],predicted.vol[i,1]),col=i,lty=i,lwd=1)
      }
      }
  })

    output$lognormal2 <- renderPlot({
      all_data              <- all_data[all_data$LogNormalVol>0,]
      all_data$LogNormalVol <- (log10(all_data$LogNormalVol)+1)/0.1

      if(is.null(input$zoom) |is.na(input$zoom)  ){
        return()
      }else{
      input$zoom
      ahead  <- isolate(input$ahead)
      paths  <- isolate(input$paths)
      und_   <- isolate(input$Underlying)
      exp_   <- isolate(input$Expiry)
      str_   <- isolate(input$Strike)
      seed   <- isolate(input$seed)

      imp    <- subset(all_data,all_data$UND==und_)
      imp    <- subset(imp     ,imp$EXP==exp_)
      imp    <- subset(imp     ,imp$Strike==str_)
      imp    <- imp[!duplicated(imp$Date),]
      imp    <- imp$LogNormalVol/100


      set.seed(seed)

      estimate.I  <- ts(replicate(paths, simulate(model1.3, nsim=ahead, xreg = 1259+1:ahead ,future = TRUE)),start=1259+1)
      estimate.II <- ts(replicate(paths, simulate(model2.3, nsim=ahead, xreg = 1259+1:ahead ,future = TRUE)),start=1259+1)

      predicted.vol <-c() 

      for(i in 1:paths){
        projected.PCs          <- cbind(estimate.I[,i],estimate.II[,i])
        reconstructed.F        <- projected.PCs%*%t(R)[1:2,]
        reconstructed.F_scaled <- matrix(rep(mu,times=nrow(reconstructed.F)),byrow=TRUE,ncol=14) + reconstructed.F * matrix(rep(sigma,times=nrow(reconstructed.F)),byrow=TRUE,ncol=14)

        predict.df      <- data.frame(Date=c(1:ahead),
                                      LogNormalVol=rep(NA,times=length(c(1:ahead))),
                                      UND    = as.numeric(rep(und_,times=length(c(1:ahead)))), 
                                      EXP    = as.numeric(rep(exp_,times=length(c(1:ahead)))), 
                                      Strike = as.numeric(rep(str_,times=length(c(1:ahead)))),
                                      F1 =reconstructed.F_scaled[,1] ,
                                      F2 =reconstructed.F_scaled[,2] ,
                                      F3 =reconstructed.F_scaled[,3] ,
                                      F4 =reconstructed.F_scaled[,4] ,
                                      F5 =reconstructed.F_scaled[,5] ,
                                      F6 =reconstructed.F_scaled[,6] ,
                                      F7 =reconstructed.F_scaled[,7] ,
                                      F8 =reconstructed.F_scaled[,8] ,
                                      F9 =reconstructed.F_scaled[,9] ,
                                      F10=reconstructed.F_scaled[,10],
                                      F11=reconstructed.F_scaled[,11],
                                      F12=reconstructed.F_scaled[,12],
                                      F13=reconstructed.F_scaled[,13],
                                      F14=reconstructed.F_scaled[,14])

        predicted.vol2 <- predict(PR2,newdata=predict.df)
        predicted.vol  <- rbind(predicted.vol,predicted.vol2)
      }
      predicted.vol <-(predicted.vol+1)/0.1
      predicted.vol <- predicted.vol/100
        all       <- cbind(matrix(rep(imp,times=paths),nrow=paths,byrow=TRUE),predicted.vol)

        xlim      <- isolate(input$range)
        ylim      <- c(min(all[,isolate(input$range)[1]:(isolate(input$range)[2]-1)]),
                       max(all[,isolate(input$range)[1]:(isolate(input$range)[2]-1)]))


         for(i in 1:paths){
          if(i==1){
          if(length(imp)==0){
            plot(c(0,1),c(0,1),type="n", xlab="",ylab="", xaxt='n', yaxt='n')
            legend(0.15,0.6,"Data not available",cex=1.5)
          }else{
            plot(imp,type="l",xlim=xlim,ylab="Log-Normal Vol", xlab="Steps",cex.lab=0.8,lty=1,lwd=2,col="darkblue",ylim=ylim,
                 main="Zoom In Plot")
            #legend("topleft",c("Observed","Projected"),col=c("darkblue","darkgreen"),lty=1)

            }
        }
        lines(c((length(imp)+1):(length(imp)+ahead)),predicted.vol[i,],col=i,lty=i,lwd=1)
        lines(c(length(imp),length(imp)+1),c(imp[length(imp)],predicted.vol[i,1]),col=i,lty=i,lwd=1)
         }
      }
    })

    output$Range <- renderUI({

      if(is.na(input$ahead)|is.null(input$ahead)){
        return()
      }else{

      ahead  <- input$ahead
      und_   <- input$Underlying
      exp_   <- input$Expiry
      str_   <- input$Strike


      imp    <- subset(all_data,all_data$UND==und_)
      imp    <- subset(imp     ,imp$EXP==exp_)
      imp    <- subset(imp     ,imp$Strike==str_)
      imp    <- imp[!duplicated(imp$Date),]
      imp    <- imp$LogNormalVol/100

      ahead <- input$ahead
      sliderInput("range", "Step Range Zoom In", min=1, max = length(imp)+ahead, value=c(length(imp)-50,length(imp)+ahead),step=1)
      }
    })

   })

ui.R:

library(shiny)
library(markdown)
library(shinythemes)
require(rsconnect,quietly = TRUE)

shinyUI(fluidPage(title="Swaption Implied Vol Projector",
                  theme = shinytheme("cerulean"),

                  fluidRow(
                  column(3, h2("Swaption Implied Vol Predictor"),
                            h3("Log Normal Vols"),
                            numericInput("ahead", label = "Number of Steps", value = 252),
                            numericInput("paths", label = "Number of Paths", value = 1),
                            numericInput("seed" , label = "Random Seed"    , value = 1)
                            ),
                  column(9,
                            mainPanel(
                              plotOutput("lognormal")
                              )
                            )
                  ),

                  fluidRow(
                    column(3,
                           selectInput("Underlying", label = "Underlying (Years):",
                                       choices = c(1,2,3,4,5,6,7,8,9,10,15,20,25,30), selected =10),
                           selectInput("Expiry", label ="Expiry (Years):",
                                       choices = c(1/12,3/12,6/12,1,2,3,4,5,7,10,15,20,25,30), selected =10),
                           selectInput("Strike", label ="Strike (%):",
                                       choices = c(-2.5,-2,-1.5,-1,-0.5,0,0.5,1,1.5,2,2.5), selected =0),
                           p(actionButton("run",
                                          "Run simulation", icon("random"))),
                           uiOutput("Range"),
                           p(actionButton("zoom",
                                          "Zoom In!"))
                           ),
                    column(9,  
                           mainPanel(
                             tags$style(type="text/css",
                                        ".shiny-output-error { visibility: hidden; }",
                                        ".shiny-output-error:before { visibility: hidden; }"
                             ),
                            plotOutput("lognormal2")
                            ))
                  )

))

Can anyone spot what am I missing?

Thank you!

Best Answer

Maybe you can try req(input$run) instead of using:

if(is.null(input$run) |is.na(input$run)  ){
    return()
}

For more information, you can refer to RStudio's article on req.