Editable table 1 values update summary values in table 2, but table 2 inputs get removed on subsequent edits

shiny

#1

Hello! I've made a small reproducible example based partially on this thread.

What I'm trying to do: I have two editable tables, where the summary values of the top table partially depend on edits made in the bottom table Petal.Width column updates. When the user updates the bottom table values of that column, their values will be summarized in the top table value[[1]] cell. The problem starts when I also want to update other top table cells independently of the bottom table updates made so far. Example:

  1. I change a value in the bottom table which updates the top table
  2. I update a value in the top table
  3. I change a value in the bottom table again which clears any independent changes made to the top table in point 2)

Ideally I would like those changes to accumulate incrementally.

Questions:

  1. Is my current approach of using eventReactive() wrapped into observe(), reactiveValues() and finally ObserveEvent() optimal? I created this code based on a couple of different examples I was able to find online but I have trouble understanding the true nature of all those dependencies and functions used. I was reading already a couple of different references (including shiny website) but I'm missing a step-by-step guide to really putting all of this together.

  2. How can I achieve this level of dependency-indenpendency of the top table from bottom table I mentioned above in the example?

Here's my current code:

library(tidyverse)
library(shiny)
library(DT)


shinyApp(
  ui = fluidPage(
    actionButton(
      inputId = "go",
      label = "Update"
    ),
    DTOutput('x1'),
    DTOutput('x2'),
    verbatimTextOutput("print")
  ),
  server = function(input, output, session) {
    
    evt_go_iris <- eventReactive(input$go, {
      iris
    })
    
    evt_go_mtcars <- eventReactive(input$go, {
      mtcars %>% 
        gather() %>%
        group_by(key) %>%
        summarise(value = sum(value))
    })
    
    rec_val = reactiveValues(df = NULL)
    
    observe({
      tmp_iris   <- evt_go_iris()
      tmp_mtcars <- evt_go_mtcars()

      rec_val$iris   <- tmp_iris
      rec_val$mtcars <- tmp_mtcars
    })
    
    output$x1 = renderDT(
      rec_val$mtcars,
      editable = TRUE
    )
    
    output$x2 = renderDT(rec_val$iris, selection = 'none', editable = TRUE)
    
    observeEvent(input$x2_cell_edit, {
      info = input$x2_cell_edit
      str(info)
      i = info$row
      j = info$col
      v = info$value
      
      rec_val$iris[i, j] <- isolate(DT::coerceValue(v, rec_val$iris[i, j]))
      
      rec_val$mtcars$value[[1]] <- sum(rec_val$iris$Petal.Width)
    })
    
    output$print <- renderPrint({
      rec_val$iris
    })
  }
)

#2

What do you mean by "partially" depends? Are you saying that once a top table cell is modified, it should override whatever value would otherwise be there, regardless of what happens in the bottom table? Or that there are some cells in the top table that are editable and don't relate to the bottom table, while other cells shouldn't be editable and do relate to the bottom table?


#3

I mean precisely this:

Or that there are some cells in the top table that are editable and don't relate to the bottom table, while other cells shouldn't be editable and do relate to the bottom table?

So let's imagine the following situation that I would like to achieve:

  1. I modify a couple elements in the bottom table and their values are summarised in the top table

  2. Then I modify another cell, unrelated to the summary cell that summarises data from point 1), in the top table

  3. I would like to further amend elements in the bottom table so that their changes are incrementally added to point 1), while still preserving the change made to the unrelated cell in point 2) -> that's the point where my app is currently failing


#4

Oh, that's pretty simple then. You already have a "single source of truth" for the top table, in rec_val$mtcars. The only problem was that you weren't having the edits to x1 update that single source of truth. Adding this observer seems to fix it:

    observeEvent(input$x1_cell_edit, {
      info = input$x1_cell_edit
      i = info$row
      j = info$col
      v = info$value
      rec_val$mtcars[i,j] <- DT::coerceValue(v, rec_val$mtcars[i,j])
    })

#5

Oh, wow - that was way easier than I thought! I guess it's because I can't completely wrap my head around different functionalities of Shiny yet. Thank you very much for your help @jcheng! Other than that, is everything correct in my code above?


closed #6

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.