samedi 22 avril 2017

R - Random number generation in ggplot and Shiny

I am building a plot of Net Present Value (NPV), using FinCal package, and its odds. For the NPV, the cash-flows are simulated using a triangular distribution for sales, normal distribution for costs and so on. So, here is a snippet of what I am doing:

npvCdf <- function(n) {
  N <- sort(n)
  P <- ecdf(N)
  return(P)
}

makePlot <- function(C, m) {
  N <- m$NPV / C$MILLION
  P <- npvCdf(N)
  #
  # NPV distribution curve
  n <- sort(N)
  p <- P(n) * 100
  df <- data.frame(npv = n, odds = p)
  #
  # Points of interest
  o <- C$NPV_BREAK_EVEN_WORST_ODDS
  q <- round((quantile(n, o)), C$DIGITS)
  e <- C$NPV_BREAK_EVEN_VALUE
  b <- P(e) * 100   # THIS IS THE ERROR I CANT FIGURE OUT
  w <- o * 100
  s <- getBreakEven(C, m)
  #
  # Labels
  npvOdds <- paste("Odds of break-even : ", b, "%")
  salesThresh <- paste("Sales threshold : ", s)
  worstCase <-
    paste("Worst case (@ 5% odds) : ", q, "million")
  #
  # Make plot
  #
  g <- ggplot(df, aes(x = npv, y = odds)) +
    geom_line(colour = "blue") +
    labs(title = "NPV and Odds") +
    labs(x = "NPV (million)") +
    labs(y = "Percent (%)") +
    geom_vline(xintercept = e,
               colour = "red",
               linetype = "longdash") +
    geom_hline(yintercept = b,
               colour = "green",
               linetype = "longdash") +
    geom_vline(xintercept = q,
               colour = "green",
               linetype = "dotdash") +
    geom_hline(yintercept = w,
               colour = "red",
               linetype = "dotdash")

The C is a data frame of all the constants that are used for calculations of cash-flows, NPV calculations, etc. For example, C$MILLION=1000000 used to divide NPV for simpler representation. The m is a data-frame of sales, cash-flows and NPV per simulation. The simulations are used for cash-flows (triangular distribution), variable cost (normal distribution) and so on.

And, here is the Shiny code that uses the above snippet.

library(shiny)
source("../npd-c.R")
# Define server logic 
shinyServer(function(input, output) {
  output$npdPlot <- renderPlot({

    C <- data.frame(2017,5000,1000000,3,100,500000,0.0,0.05,0.1,
                    input$salesRange[1],
                    input$salesRange[2],
                    input$salesMode,
                    input$demDeclMean,
                    input$demDeclSd,
                    input$varCostMean,
                    input$varCostSd,
                    input$fixedCostRange[1],
                    input$fixedCostRange[2]
                    )
    names(C) <-
      c(
        "SEED",
        "ITERATIONS",
        "MILLION",
        "DIGITS",
        "PRICE",
        "OUTLAY",
        "NPV_BREAK_EVEN_VALUE",
        "NPV_BREAK_EVEN_WORST_ODDS",
        "HURDLE_RATE",
        "SALES_TRIANG_MIN",
        "SALES_TRIANG_MAX",
        "SALES_TRIANG_MODE",
        "DEM_DECL_FACTOR_MEAN",
        "DEM_DECL_FACTOR_SD",
        "VAR_COST_RATE_MEAN",
        "VAR_COST_RATE_SD",
        "FIX_COST_RATE_MIN",
        "FIX_COST_RATE_MAX"
      )

    n <- npd(C,-1)
    g <- makePlot(C,n)
    g
  })
})

The problem is as follows.

The same code when run in R, I get the plot right in terms of the NPV curve, horizontal and vertical lines. Whereas, when run as a Shiny application, the horizontal and vertical lines are hugely displaced. This is despite, hiving of the NPV and cash-flows code into a separate .R file and setting the same seed value for both the Shiny and non-shiny versions. For example, P(0)=40.07 without Shiny and P(0)=4.7 with Shiny application.

What am I missing?




Aucun commentaire:

Enregistrer un commentaire