I am making a shiny app as a hobby which is a model with variables that change over time depending on both inputs and other calculated fields. I've done this using a sliderinput and observeevent for time, with tabs for each point in time and reactives for each variable at each point in time but this creates a lot of duplication in both the ui and the server.
Is there a more elegant/efficient way of doing this? I understand reactivevalues can be used to create a reactive list but all the examples I've seen of this are individually defined values.
I'm hoping there is some way of defining the calculation across all values , e.g. in the reprex below something like ccc(n) <- reactive( input$a(n) * 2 + bbb(n-1)() * 3)
I've tried to make a reprex to show the kind of thing i'm trying to do. The real use case I'm working on has more variables and more points in time. The approach making different reactives for each variable at each point in time seems to work but I'm concerned about the effort needed to update each one if i need to change a calculation in future. thanks for any help
''''
#package and data load
library(shiny)
library(dplyr)
#some read csv and other reference data used in formulas
#UI -------------------------------------------
ui <- fluidPage(
#tabs for each point in time
sidebarLayout(
mainPanel(
sliderInput(inputId = "time",
label = "Hour",
value = 1, min = 1, max = 3, width = '1000px'
),
),
mainPanel(
tabsetPanel(
id = "tabset",
type = "hidden",
# hour0 ==================
tabPanel("1",
fluidRow(
column(4,
#text input for first value
numericInput(inputId = "a1", label = "A1", value = 1),
),
column(4,
# text input for b1
numericInput(inputId = "b1", label = "B1", value = 0),
),
column(4,
#text output for c1
fluidPage(tags$b("C1")),
fluidPage(textOutput(outputId = "c1")),
),
),
),
tabPanel("2",
fluidRow(
column(4,
#text input for first value
numericInput(inputId = "a2", label = "A2", value = 1),
),
column(4,
#text output for b2
fluidPage(tags$b("b2")),
fluidPage(textOutput(outputId = "b2")),
),
column(4,
#text output for c1
fluidPage(tags$b("C2")),
fluidPage(textOutput(outputId = "c2")),
),
),
),
tabPanel("3",
fluidRow(
column(4,
#text input for first value
numericInput(inputId = "a3", label = "A3", value = 1),
),
column(4,
#text output for b2
fluidPage(tags$b("b3")),
fluidPage(textOutput(outputId = "b3")),
),
column(4,
#text output for c1
fluidPage(tags$b("C3")),
fluidPage(textOutput(outputId = "c3")),
), ), ), ), ), ), )
#Server ---------------------------------------------------
server <- function(input, output, session) {
#observe slider update to change time
observeEvent(input$time, {
updateTabsetPanel(session, "tabset", selected = paste0(input$time))
})
#hour 1 ---------------------------------------------
#A is input for hour 1
#B is input for hour 1
#text output for C hour 1
ccc1 <- reactive(input$a1 * 2)
output$c1 <- renderText(ccc1())
#hour 2 ---------------------------------------------
#A is input for hour 1
#text output for B hour 2
bbb2 <- reactive(input$a2 * 10)
output$b2 <- renderText(bbb2())
#text output for C hour 2
ccc2 <- reactive(input$a2 * 2 + input$b1 * 3)
output$c2 <- renderText(ccc2())
#hour 3 ---------------------------------------------
#A is input for hour 3
#text output for B hour 3
bbb3 <- reactive(input$a3 * 10)
output$b3 <- renderText(bbb3())
#text output for C hour 3
ccc3 <- reactive(input$a3 * 2 + bbb2() * 3)
output$c3 <- renderText(ccc3())
}
shinyApp(ui, server)
''''