Home > Back-end >  In R Shiny, how to eliminate a custom function that is no longer needed?
In R Shiny, how to eliminate a custom function that is no longer needed?

Time:09-25

I am simplifying a web of tangled code and I am about halfway there with the below MWE. The below as posted runs as intended (for me). If the code looks confusing, it was much worse before.

Please look at vectorVariable in server section, marked with # ???. Why does the first vectorVariable work, whereby the 2nd vectorVariable immediately beneath it, commented out, causes an error message when uncommented (and the first one commented out) and running the App? The first vectorVariable references vectorMultiFinal which has been neutered by passing its values straight on to vectorMulti, and the 2nd vectorVariable goes straight to the vectorMulti function. (In my process of simplifying, I merged the functions of vectorMultiFinal into vectorMulti and left vectorMultiFinal as a pass-through "shell" so I could make sure the App continues working every step of simplification).

The purpose of the App is to present the user with a default x value in slider input and a default y value in 1st matrix (flatRate function), and then "build a curve" around that base in the 2nd matrix (curveRate function) by manipulating/adding x and y values in the matrices.

Note that in the version of shinyMatrix package that I'm running, when presented with a 2 column matrix, I have to input into the right-most column first and then go left. There's a minor bug in shinyMatrix that I need to download the fix for from gitHub.

MWE code:

rm(list = ls())

library(shiny)
library(shinyMatrix)

### 1st user input matrix ###
flatRate <- function(inputId){
  matrixInput(inputId, 
              value = matrix(c(0.05), 1, 1, dimnames = list(c("Initial rate (Y)"),NULL)),
              rows = list(extend = FALSE, names = TRUE),
              cols = list(extend = FALSE, names = FALSE, editableNames = FALSE),
              class = "numeric")} 

### 2nd user input matrix ###
curveRate <- function(InputId,x,y){ # x = period to apply y, y = variable applied in period x
  matrixInput(InputId,
              value = matrix(c(x,y),1,2,dimnames=list(NULL,c("Period X","Curved rate Y"))),
              rows = list(extend = TRUE,  names = FALSE),
              cols = list(extend = FALSE, names = TRUE, editableNames = FALSE),
              class = "numeric")}  

### Corrects user inputs in "curveRate" input matrix ###
curveCorrect <- function(x,y){ # x = slider input model periods, y = "curveRate" inputs
  a <- y
  a[,1][a[,1]>x] <- x          # a assigns value of period x to any input period in "curveRate" > x
  b <- diff(a[,1,drop=FALSE])  # b ensures "curveRate" period inputs are in increasing order
  b[b<=0] <- NA                # flag any instances of period inputs in decreasing order with NA
  b <- c(1,b)                  # See above 2 explanations
  a <- cbind(a,b)
  a <- na.omit(a)              # deletes rows with element NA
  a <- a[,-c(3),drop=FALSE]    # deletes column inserted above to flag NA
  return(a)}

### Interpolates & spreads matrix inputs across even time horizon ###
vectorMulti <- function(x,y){ # x = number of modeled periods, y = "curveCorrect" output
  a <- rep(NA, x)                                                     # generates single column vector of NA numbering x periods
  a[y[,1]] <- y[,2]                                                   # places each variable y[,2] in position indicated by its respective period y[,1]
  a[seq_len(min(y[,1])-1)] <- a[min(y[,1])]                           # if 1st period y[,1] > 1, applies that variable y[,2] to all periods <= y[,1]
  if(max(y[,1]) < x){a[seq(max(y[,1]) 1, x, 1)] <- 0}                 # applies 0 to all periods after max period specified in y[,1] up to period x
  a <- approx(seq_along(a)[!is.na(a)],a[!is.na(a)],seq_along(a))$y    # the only NA's remaining, after the above, are periods to interpolate using approx
  b <- seq(1:x)                                                       # creates single column vector for number of x periods
  c <- data.frame(x=b,y=a)                                            # merges b and a into data frame, assigns column header labels of x and y
  return(c)}

vectorMultiFinal <- function(x,y){vectorMulti(x,curveCorrect(x,y))} # ???

ui <- fluidPage(
        column(9,
                sliderInput('periods','Periods (X):',min=1,max=12,value=6),
                flatRate("ratesBaseInput"),
                actionButton('resetRatesVectorBtn','Reset'),
                uiOutput("ratesVectors"),
                plotOutput("plot1"),
        )
      )

server <- function(input,output,session)({
  
  periods        <- reactive(input$periods)
  ratesBaseInput <- reactive(input$ratesBaseInput)
  ratesInput     <- reactive(input$ratesInput)
  
  vectorVariable <- function(y){vectorMultiFinal(periods(),curveCorrect(periods(),y))} # ???
  # vectorVariable <- function(y){vectorMulti(periods(),curveCorrect(periods(),y))}    # ???
  
  rates <- function(){vectorVariable(ratesInput())}
  
  output$ratesVectors <- renderUI({
    input$resetRatesVectorBtn
    curveRate("ratesInput",input$periods,input$ratesBaseInput[1,1])
  }) # close render UI
  
  output$plot1 <-renderPlot({plot(rates())})
 
}) # close server

shinyApp(ui, server)

CodePudding user response:

Use req() to resolve your issue.

server <- function(input,output,session)({
  
  periods        <- reactive(input$periods)
  ratesBaseInput <- reactive(input$ratesBaseInput)
  ratesInput     <- reactive(input$ratesInput)
  
  #vectorVariable <- function(y){vectorMultiFinal(periods(),curveCorrect(periods(),y))} # ???
  vectorVariable <- function(y){vectorMulti(periods(),curveCorrect(periods(),y))}    # ???
  
  rates <- function(){vectorVariable(req(ratesInput()))}  ####<-------   use req()
  
  output$ratesVectors <- renderUI({
    req(input$periods,input$ratesBaseInput)
    input$resetRatesVectorBtn
    curveRate("ratesInput",input$periods,input$ratesBaseInput[1,1])
  }) # close render UI
  
  output$plot1 <-renderPlot({req(rates())
    plot(rates())})
  
}) # close server
  • Related