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)

''''