Home > other >  In R, why is one function working and the other not working when they are both very similar numeric
In R, why is one function working and the other not working when they are both very similar numeric

Time:10-21

In running the below MWE code as presented, it runs interpolation scenarios fine. However if I comment-out the first custom interpol() function that is currently uncommented, and uncomment the second interpol() function, the results do not plot. WHY?? They are so similar in output form!

I ran both interpol() versions in R studio console to test. They both work as they should. They are both vectors when I ran is.vector(), they are both numeric when I ran is.numeric().

Obviously the 2nd interpol() doesn't interpolate, it calculates a sumproduct (testing sumproduct for evolution of this code). Under the default scenario, it generates a vector of 10 elements, each element = 5. Why in the world would this not plot out just like the first interpol()?

MWE code:

library(shiny)
library(shinyMatrix)
library(dplyr)
library(ggplot2)

interpol <- function(a, b) { # a = periods, b = matrix inputs
  c    <- rep(NA, a)
  c[1] <- b[1]
  c[a] <- b[2]
  c    <- approx(seq_along(c)[!is.na(c)], c[!is.na(c)], seq_along(c))$y
  return(c)
}

# interpol <- function(a, b) { # a = periods, b = matrix inputs
#   c    <- rep(NA, a)
#   c[]  <- sum(b[,1]) %*% sum(b[,2])
#   return(c)
# }

ui <- fluidPage(
  sliderInput('periods', 'X-axis periods:', min=1, max=10, value=10),
  matrixInput(
    "myMatrixInput",
    label = "Values to sumproduct paired under each scenario heading:",
    value =  matrix(c(1, 5), 1, 2, dimnames = list(NULL, rep("Scenario 1", 2))),
    cols = list(extend = TRUE,  delta = 2, names = TRUE,  delete = TRUE, multiheader = TRUE),
    rows = list(extend = FALSE, delta = 1, names = FALSE, delete = FALSE),
    class = "numeric"),
  plotOutput("plot")
)

server <- function(input, output, session) {
  
  observeEvent(input$myMatrixInput, {
    tmpMatrix <- input$myMatrixInput
    
    # Remove any empty matrix columns
    empty_columns <- sapply(tmpMatrix, function(x) all(is.na(x) | x == ""))
    tmpMatrix <- tmpMatrix[, !empty_columns, drop=FALSE]
    
    # Assign column header names
    colnames(tmpMatrix) <- paste("Scenario", rep(1:ncol(tmpMatrix), each = 2, length.out = ncol(tmpMatrix)))
    
    isolate( # isolate update to prevent infinite loop
      updateMatrixInput(session, inputId = "myMatrixInput", value = tmpMatrix)
    )
  })
  
  plotData <- reactive({
    tryCatch(
      lapply(seq_len(ncol(input$myMatrixInput)/2),
             function(i){
               tibble(
                 Scenario = colnames(input$myMatrixInput)[i*2-1],
                 X = seq_len(input$periods),
                 Y = interpol(input$periods, input$myMatrixInput[1,(i*2-1):(i*2)])
               )
             }) %>% bind_rows(),
      error = function(e) NULL
    )
  })
  
  output$plot <- renderPlot({
    req(plotData())
    plotData() %>% ggplot()   geom_line(aes(
      x = X,
      y = Y,
      colour = as.factor(Scenario)
    ))
  })
  
}

shinyApp(ui, server)

CodePudding user response:

To make it easier to explain I would refer the first function as interpol1 and the second function as interpol2.

In lapply where you are calling the function (interpol(input$periods, input$myMatrixInput[1,(i*2-1):(i*2)])) input$myMatrixInput[1,(i*2-1):(i*2)] returns a numeric vector and not matrix. In interpol1 you use b[1] and b[2] to subset the values of b which is correct way to subset a vector but in interpol2 you use b[,1] and b[,2] to subset the vector which is incorrect and returns an error Error in b[, 1] : incorrect number of dimensions. I think you were expecting b to be a matrix hence you used b[, 1].

One fix would be to keep the input as matrix which can be done by using -

Y = interpol1(input$periods, input$myMatrixInput[1,(i*2-1):(i*2), drop = FALSE])

This should work for both the functions interpol1 and interpol2.

  • Related