Subaru Spirit
Subaru Spirit

Reputation: 464

R shiny use dynamic UI's input to multiply by group summed values

This is an extension of my previous problem. I have a numericInput called Number of modalities. When the Number of modalities changes, there will be more modality minutes, and more groups of columns. Please refer to the below 2 pics for illustration.

Now what I want is, the value inside modality minutes to multiply by its group sum, and finally the sum of the whole group. For example, if there are 2 Number of modalities, I want a column called Total_minutes = (2WW1+Urgent1+Routine1)* value inside Modality 1 minutes + (2WW2+Urgent2+Routine2)* value inside Modality 2 minutes.

Although the value at the moment are all 1 inside those columns, but those values will be varied in real world use.

Please help, I've been stuck for a long time on this problem and would really appreciate any help, thanks!

pic1

pic2

library(shiny)
library(reactable)
library(tidyverse)


ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      numericInput("No_modalities", label = "Number of modalities",
                   value = 1, min = 1, max = 100, step = 1),
      textInput("urgency1", label = "Urgency 1", value = "2WW"),
      textInput("urgency2", label = "Urgency 2", value = "Urgent"),
      textInput("urgency3", label = "Urgency 3", value = "Routine"),
      uiOutput("modality"),
      width = 3
    ),
    mainPanel(
      reactableOutput("template"),
      textOutput("check")
      , width = 9
    )
  )
)

server <- function(input, output, session) {
  modality_names <- reactive(paste0("Modality ", seq_len(input$No_modalities)))
  
  output$modality <- renderUI({
    map(modality_names(), ~ textInput(.x, label = paste(.x," minutes"),
                                      value = isolate(input[[.x]])))
  })
  
  df1 = reactive({
    tibble(Column1 = rep(1,10), Column2 = rep(2,10))
  })
  
  # columns to add
  columnsToAdd = reactive({
    c(outer(c(input$urgency1,input$urgency2,input$urgency3),
            seq_len(input$No_modalities), paste0))
  })
  
  df2 = reactive({add_column(df1(),!!!set_names(as.list(rep(1,
                                                            length(columnsToAdd()))),
                                                nm=columnsToAdd()))})
  
  output$template = renderReactable({
    reactable(df2())
  })
  
  
}

shinyApp(ui, server)

Upvotes: 1

Views: 231

Answers (1)

zx8754
zx8754

Reputation: 56159

Update below two reactive objects, and it should work.

Change the textInput to numericInput

output$modality <- renderUI({
  map(modality_names(), ~ numericInput(.x, label = paste(.x," minutes"),
                                       value = isolate(input[[.x]])))
})

Assuming we are starting from 3rd column and there are 3 urgencies for each modality, subset every 3 columns and rowSums, then do matrix multiplication using %*% by input modalities which we are getting using sapply loop

output$template = renderReactable({
  res <- df2()
  res$Total_minutes <- sapply(seq(3, ncol(res), 3), function(i){ 
    rowSums(res[, i + 0:2])
  }) %*% sapply(modality_names(), function(i){ input[[ i ]] })
  
  reactable(res)
})

enter image description here

Upvotes: 2

Related Questions