Home > Net >  How to collapse repeated functions into a master function?
How to collapse repeated functions into a master function?

Time:10-08

The MWE code below works as intended. However, how I got here seems sloppy with the shinyMatrix package function, matrixInput, repeated 3x and my attempt to consolidate these into custom functions firstInput and secondInput. Is there recommended best practice for consolidating repeated functions? Or is it better to eliminate my firstInput and secondInput and just use the longer matrixInput throughout for understandability/debugging reasons?

library(shiny)
library(shinyMatrix)

firstInput <- function(inputId,y){ # << y = y col default value of input matrix
  matrixInput(inputId, 
              value = matrix(c(10,5), 1, 2, dimnames = list(c("1st input"),c("X and Y",""))),
              rows =  list(extend = FALSE, names = TRUE),
              cols =  list(
                           extend = FALSE, 
                           names = TRUE, 
                           editableNames = FALSE,
                           multiheader=TRUE
                          ),
              class = "numeric")}

secondInput <- function(inputId,y){ # << y = y col default value of input matrix
  matrixInput(inputId, 
              value = matrix(c(10,y), 1, 2, dimnames = list(c("2nd input"),c(1,""))),
              label = "Add, delete, or modify matrix parameters:",
              rows =  list(extend = FALSE, names = TRUE),
              cols =  list(
                           extend = TRUE,
                           delta = 2,
                           delete = TRUE,
                           names = TRUE, 
                           editableNames = FALSE,
                           multiheader=TRUE
                          ),
              class = "numeric")}

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      uiOutput("panel"),
      actionButton("showSecond","Show 2nd input (modal)",width = "100%")
    ),
    mainPanel(plotOutput("plot1"))
  )
)

server <- function(input, output, session){
 
  output$panel <- renderUI({firstInput("input1")})
  
  observeEvent(input$showSecond,{
    showModal(
      modalDialog(
        if(is.null(input$input2))
          {secondInput("input2",input$input1[1,2])} else
           {matrixInput("input2",
                         value = input$input2,
                         label = "Add, delete, or modify matrix parameters:",
                         rows =  list(extend = FALSE, names = TRUE),
                         cols =  list(
                                      extend = TRUE,
                                      delta = 2,
                                      delete = TRUE,
                                      names = TRUE,
                                      editableNames = FALSE,
                                      multiheader=TRUE
                                     ),
                        class = "numeric")
            }, # closes else
        footer = modalButton("Close")
      ))
  })
  
  observe({ # << Assign sequential col header to matrix based on groupings of two
    req(input$input2)
    mm <- input$input2
    colnames(mm) <- trunc(1:ncol(mm)/2) 1 
    isolate(updateMatrixInput(session, "input2", mm))
  })
  
  output$secondInput <- renderUI({
    req(input$input1)
    secondInput("input2",input$input1[1,2])
  })
  
  outputOptions(output,"secondInput",suspendWhenHidden = FALSE) 
  
  output$plot1 <-renderPlot({
    req(input$input1)
    plot(rep(if(isTruthy(input$input2)){input$input2[1,2]} else {input$input1[1,2]}, times=10))
  })
  
}

shinyApp(ui, server)

CodePudding user response:

Below is the MWE code with a consolidation of the various matrixInput functions used in the original post. I hope this is understandable! At least it's shorter than the original post.

library(shiny)
library(shinyMatrix)

###################################################################################################
#  a = matrix to input into matrixInput            d = delta # of columns when extending columns  #
#  b = variable for y column of input matrix       e = user option to delete column               #
#  c = extend matrix columns (T/F)                                                                #
################################################################################################### 

# matValues... feed into matrixInput as initial matrix; b parameter is for initial "Y" value
  matValue1 <- function(b){matrix(c(10,b), 1, 2, dimnames = list(c("1st input"),c("X and Y","")))}
  matValue2 <- function(b){matrix(c(10,b), 1, 2, dimnames = list(c("2nd input"),c(1,"")))}

myInput <- function(inputId,a,c,d,e){ 
  matrixInput(inputId, 
              value = a,
              rows =  list(extend = FALSE, names = TRUE),
              cols =  list(extend = c, 
                           delta = d,
                           delete = e,
                           names = TRUE, 
                           editableNames = FALSE,
                           multiheader=TRUE),
              class = "numeric")}

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      uiOutput("panel"),
      actionButton("showSecond","Show 2nd input (modal)",width = "100%")
    ),
    mainPanel(plotOutput("plot1"))
  )
)

server <- function(input, output, session){
 
  output$panel <- renderUI({myInput("input1",matValue1(256),FALSE,1,FALSE)})
  
  observeEvent(input$showSecond,{
    showModal(
      modalDialog(
        if(is.null(input$input2))
          {myInput("input2",matValue2(input$input1[1,2]),TRUE,2,TRUE)}
            else {myInput("input2",input$input2,TRUE,2,TRUE)}, 
        footer = modalButton("Close")
      ))
  })
  
  observe({ # << Assign sequential col header to matrix based on groupings of two
    req(input$input2)
    mm <- input$input2
    colnames(mm) <- trunc(1:ncol(mm)/2) 1 
    isolate(updateMatrixInput(session, "input2", mm))
  })
  
  output$secondInput <- renderUI({
    req(input$input1)
    myInput("input2",matValue2(input$input1[1,2]),TRUE,2,TRUE)
  })
  
  outputOptions(output,"secondInput",suspendWhenHidden = FALSE) 
  
  output$plot1 <-renderPlot({
    req(input$input1)
    plot(rep(if(isTruthy(input$input2)){input$input2[1,2]} else {input$input1[1,2]}, times=10))
  })
  
}

shinyApp(ui, server)
  • Related