2

I have this problem and the closest I can find is in reference to the submission here but it doesn't quite address what I'm trying to solve Reactive shiny modules sharing data

Referring to the corrected example in the link above, what if I want to be able to edit table a (cells in column x_2), and this will automatically update table c (the corresponding cells in column x_2).

Thanks

bct
  • 45
  • 3

1 Answers1

0

Here is a bit simpler version that doesn't work with proxies (and uses the new module interface), I hope it is ok. You can change any value in the first 2 tables and the 3rd table shows the sum and is updated. The trick is that the modules where you edit data have to return the edited data as reactives, these are saved as variables in the main server function. The module that updates based on this data needs to take these variables as reactive inputs.

Very important is:

  • the modules that return data need to return a reactive, the easiest way to do this is return(reactive({returnvalue}))
  • in the server function the reactives passed to the module mustn't be evaluated, e.g. you have to use my_reactive_value instead of my_reactive_value()
### Libraries
library(shiny)
library(dplyr)
library(DT)

### Data----------------------------------------
set.seed(4)
table_a <- data.frame(
  id=seq(from=1,to=10),
  x_1=rnorm(n=10,mean=0,sd=10),
  x_2=rnorm(n=10,mean=0,sd=10),
  x_3=rnorm(n=10,mean=0,sd=10)
) %>% 
  mutate_all(round,3)

table_b <- data.frame(
  id=seq(from=1,to=10),
  x_1=rnorm(n=10,mean=0,sd=10),
  x_2=rnorm(n=10,mean=0,sd=10),
  x_3=rnorm(n=10,mean=0,sd=10)
)%>% 
  mutate_all(round,3)

mod_table_edit <- function(id, data_initialisation) {
  moduleServer(
    id,
    function(input, output, session) {
      # initialise the reactive data object for the table
      data <- reactiveValues(table = data_initialisation)
      
      # render the table
      output$table <- renderDT({
        datatable(data$table,
                  editable = TRUE)
      })
      
      # update the underlying data
      observeEvent(input$table_cell_edit, {
        data$table <- editData(data$table, input$table_cell_edit)
      })
      
      # return the data as a reactive
      return(reactive(data$table))
    }
  )
}

mod_table_add <- function(id, data_input_1, data_input_2) {
  moduleServer(
    id,
    function(input, output, session) {
      # do the calculations
      data_table <- reactive({
        data_input_1() + data_input_2()
      })
      
      # render the table
      output$table <- renderDT({
        datatable(data_table())
      })
    }
  )
}

modFunctionUI <- function(id) {
  ns <- NS(id)
  DTOutput(ns("table"))
}

ui <- fluidPage(
  fluidRow(
    column(4,
           modFunctionUI("table_1")),
    column(4,
           modFunctionUI("table_2")),
    column(4,
           modFunctionUI("table_3"))
  )
)

server <- function(input, output, session) {
  # call the modules for the editable tables and store the results
  data_table_1 <- mod_table_edit("table_1", data_initialisation = table_a)
  data_table_2 <- mod_table_edit("table_2", data_initialisation = table_b)
  
  # call the module for the table that takes inputs
  # the reactives musn't be evaluated
  mod_table_add("table_3",
                data_input_1 = data_table_1,
                data_input_2 = data_table_2)
}

shinyApp(ui, server)
starja
  • 9,887
  • 1
  • 13
  • 28