Search code examples
rshinyreactivecbind

R Shiny: Creating New Columns Within a Reactive Data Frame


Say I have a data frame called summarized which includes the columns TY_COMP and LY_COMP (among others). I could write a function in R that performs a calculation on TY_COMP and LY_COMP and creates a new column called cac in the data frame like this:

summarized$cac <- summarized$TY_COMP/summarized$LY_COMP-1

cac is now a new column in the summarized data frame.

Now say that summarized() is a reactive data frame with the same columns.

How could I achieve the effect done in the non-reactive data frame, i.e. create a new column within the current frame? Or how would I get the same effect?

I tried:

summarized$cac <- reactive({summarized()$TY_COMP/summarized()$LY_COMP-1})

Solution

  • I reckon you want to modify a reactive when for example an actionButton is clicked. For this purpose I would use reactiveValues. You can modify reactiveValue inside of observers such as observe or observeEvent.

    Check out this simple example:

    summarized <- data.frame(id = 1:20, group = letters[1:4], TY_COMP = runif(20), LY_COMP = runif(20))
    
    library(shiny)
    
    ui <- fluidPage(
      verbatimTextOutput("text"),
      actionButton("btn", "Add the 'cac' column to summarized")
    )
    
    server <- function(input, output){
      rv <- reactiveValues(summarized = summarized)
    
      output$text <- renderPrint(rv$summarized)
    
      observeEvent(input$btn, {
        rv$summarized$cac <- summarized$TY_COMP / summarized$LY_COMP - 1
      })
    
      summarized_mod <- reactive({
        summarized()$TY_COMP / summarized()$LY_COMP-1
      })
    }
    
    shinyApp(ui, server)
    

    Another option would be to create another reactive that has an additional column. This is possible to use, but depending on your use case, I recommend the first solution.

    Example:

    summarized <- data.frame(id = 1:20, group = letters[1:4], TY_COMP = runif(20), LY_COMP = runif(20))
    
    library(shiny)
    
    ui <- fluidPage(
      verbatimTextOutput("text1"),
      verbatimTextOutput("text2")
    )
    
    server <- function(input, output){
    
      output$text1 <- renderPrint(summarized_orig())
      output$text2 <- renderPrint(summarized_mod())
    
    
      summarized_orig <- reactive( {
        summarized
      })
    
      summarized_mod <- reactive({
        df <- summarized_orig()
        df$cac <- summarized_orig()$TY_COMP / summarized_orig()$LY_COMP - 1
    
        df
      })
    }
    
    shinyApp(ui, server)