Lea7885
Lea7885

Reputation: 97

Edit filtered reactive data frame in shiny, save user input for use in app

I'm working on an editable table that contains reactive filters for columns AND rows. I implemented the code YBS provided and it looks exactly the way I want and displays correctly. The issue I have is that, I cannot access the updated data frame on the server side. The reason I want a data frame is so that I have information of the changed cells. Each cell value (and references) will serve as an input for a table. I tried to create a different dataframe using observeEvent on my_matrix_cell_edit and rbind but no result

Below is the reprex, when you run it, on the console side I get "NULL'. Is this caused by df <- reactiveValues(data=NULL) that is constantly resetting it?

Thanks all for your help!

country_matrix <- structure(list(industry_group = c("Financial Institutions Group (FIG)", 
                                                    "Financial Institutions Group (FIG)", "Financial Institutions Group (FIG)", 
                                                    "Financial Institutions Group (FIG)", "Financial Institutions Group (FIG)", 
                                                    "Financial Institutions Group (FIG)"), sector = c("Housing Finance", 
                                                                                                      "Climate Finance", "Climate Finance", "Trade Finance", "Housing Finance", 
                                                                                                      "Housing Finance"), component = c("Stakeholder", "Stakeholder", 
                                                                                                                                        "Environment & Social", "Stakeholder", "Environment & Social", 
                                                                                                                                        "Economywide"), subcomponent = c("Access", "Credit: Mitigation", 
                                                                                                                                                                         "Environment", "Environment", "Environment", "Economywide"), 
                                 Afghanistan = c(0, 0, 0, 0, 0, 0), Angola = c(0, 0, 0, 0, 
                                                                               0, 0), Albania = c(0, 0, 0, 0, 0, 0), Argentina = c(0, 0, 
                                                                                                                                   0, 0, 0, 0), Armenia = c(0, 0, 0, 0, 0, 0), `American Samoa` = c(0, 
                                                                                                                                                                                                    0, 0, 0, 0, 0), Azerbaijan = c(0, 0, 0, 0, 0, 0), Burundi = c(0, 
                                                                                                                                                                                                                                                                  0, 0, 0, 0, 0), Benin = c(0, 0, 0, 0, 0, 0), `Burkina Faso` = c(0, 
                                                                                                                                                                                                                                                                                                                                  0, 0, 0, 0, 0), Bangladesh = c(0, 0, 0, 0, 0, 0), Bulgaria = c(0, 
                                                                                                                                                                                                                                                                                                                                                                                                 0, 0, 0, 0, 0), `Bosnia and Herzegovina` = c(0, 0, 0, 0, 
                                                                                                                                                                                                                                                                                                                                                                                                                                              0, 0), Belarus = c(0, 0, 0, 0, 0, 0), Belize = c(0, 0, 0, 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               0, 0, 0), Bolivia = c(0, 0, 0, 0, 0, 0), Brazil = c(0, 0, 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   0, 0, 0, 0), Barbados = c(0, 0, 0, 0, 0, 0), Bhutan = c(0, 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           0, 0, 0, 0, 0), Botswana = c(0, 0, 0, 0, 0, 0), `Central African Republic` = c(0, 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          0, 0, 0, 0, 0) 
), row.names = c(NA, 6L), class = "data.frame")

### 

countrycmx <- names(country_matrix)[5:25]

ui <- fluidPage(
  

  fluidRow(
    column(12,
           column(
             2,
             pickerInput(
               "sectormx",
               'Sector',
               selected = "Climate Finance",
               choices = unique(country_matrix$sector),
               #selected = c('SME Finance', 'Insurance', 'Climate Finance'),
               multiple = TRUE)
           ),
           column(
             2,
             pickerInput(
               'componentmx',
               'Component',
               choices = unique(country_matrix$component),
               selected = 'Stakeholder',
               multiple = TRUE,
               options = pickerOptions(
                 actionsBox = TRUE,
                 liveSearch = TRUE,
                 liveSearchPlaceholder = 'Search...',
                 liveSearchNormalize = TRUE,
                 liveSearchStyle = 'contains'
               ),
               width = "100%"
             )
           ),
           column(
             2,
             pickerInput(
               'subcomponentmx',
               'Subcomponent',
               choices = unique(country_matrix$subcomponent),
               selected = 'Quality',
               multiple = TRUE,
               options = pickerOptions(
                 actionsBox = TRUE,
                 liveSearch = TRUE,
                 liveSearchPlaceholder = 'Search...',
                 liveSearchNormalize = TRUE,
                 liveSearchStyle = 'contains'
               ),
               width = "100%"
             )) ,
           column(
             2,
             pickerInput(
               'countrymx',
               'Country',
               choices = countrycmx,
               selected = 'Albania',
               multiple = TRUE,
               options = pickerOptions(
                 actionsBox = TRUE,
                 liveSearch = TRUE,
                 liveSearchPlaceholder = 'Search...',
                 liveSearchNormalize = TRUE,
                 liveSearchStyle = 'contains'
               ),
               width = "100%"
             ))

           #actionButton("update", "Update Data set", class = "btn-primary",style='padding:4px; font-size:120%')
    ),
    
    # Show a plot of the generated distribution
    column(12,
           DTOutput("my_matrix")
           
    )
  )
)


server <- function(input, output, session) {
  
  matrix <- reactive({
    req(input$sectormx, input$componentmx, input$subcomponentmx)
    
    country_matrix %>%
      dplyr::filter(
        sector %in% input$sectormx#,
      
      ) %>%
      select(sector,component,subcomponent,input$countrymx)
  })
  
  df <- reactiveValues(data=NULL)
                      
  observe({df$data <- matrix()})
  
  output$my_matrix  <- renderDT(df$data, editable = TRUE, rownames = FALSE)
  
  
  #observeEvent(input$my_matrix_cell_edit, {
    
    observeEvent(input$my_matrix_cell_edit, {
      info = input$my_matrix1_cell_edit
      str(info)
      i = info$row
      j = info$col + 1
      v = info$value
      df$data[i, j] <<- editData(info, df$data[i, j])
  })
  
}

shinyApp(ui = ui, server = server)

Upvotes: 0

Views: 684

Answers (2)

Lea7885
Lea7885

Reputation: 97

Thanks to YBS and some additional help I got a fully working solution :

library(data.table)
library(DT)
library(dplyr)
library(tidyr)


country_matrix <- structure(list(industry_group = c("Financial Institutions Group (FIG)", 
                                                    "Financial Institutions Group (FIG)", "Financial Institutions Group (FIG)", 
                                                    "Financial Institutions Group (FIG)", "Financial Institutions Group (FIG)", 
                                                    "Financial Institutions Group (FIG)"), sector = c("Housing Finance", 
                                                                                                      "Climate Finance", "Climate Finance", "Trade Finance", "Housing Finance", 
                                                                                                      "Housing Finance"), component = c("Stakeholder", "Stakeholder", 
                                                                                                                                        "Environment & Social", "Stakeholder", "Environment & Social", 
                                                                                                                                        "Economywide"), subcomponent = c("Access", "Credit: Mitigation", 
                                                                                                                                                                         "Environment", "Environment", "Environment", "Economywide"), 
                                 Afghanistan = c(0, 0, 0, 0, 0, 0), Angola = c(0, 0, 0, 0, 
                                                                               0, 0), Albania = c(0, 0, 0, 0, 0, 0), Argentina = c(0, 0, 
                                                                                                                                   0, 0, 0, 0), Armenia = c(0, 0, 0, 0, 0, 0), `American Samoa` = c(0, 
                                                                                                                                                                                                    0, 0, 0, 0, 0), Azerbaijan = c(0, 0, 0, 0, 0, 0), Burundi = c(0, 
                                                                                                                                                                                                                                                                  0, 0, 0, 0, 0), Benin = c(0, 0, 0, 0, 0, 0), `Burkina Faso` = c(0, 
                                                                                                                                                                                                                                                                                                                                  0, 0, 0, 0, 0), Bangladesh = c(0, 0, 0, 0, 0, 0), Bulgaria = c(0, 
                                                                                                                                                                                                                                                                                                                                                                                                 0, 0, 0, 0, 0), `Bosnia and Herzegovina` = c(0, 0, 0, 0, 
                                                                                                                                                                                                                                                                                                                                                                                                                                              0, 0), Belarus = c(0, 0, 0, 0, 0, 0), Belize = c(0, 0, 0, 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               0, 0, 0), Bolivia = c(0, 0, 0, 0, 0, 0), Brazil = c(0, 0, 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   0, 0, 0, 0), Barbados = c(0, 0, 0, 0, 0, 0), Bhutan = c(0, 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           0, 0, 0, 0, 0), Botswana = c(0, 0, 0, 0, 0, 0), `Central African Republic` = c(0, 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          0, 0, 0, 0, 0) 
), row.names = c(NA, 6L), class = "data.frame")

### 

countrycmx <- names(country_matrix)[5:25]

ui <- fluidPage(
  

  fluidRow(
    column(12,
           column(
             2,
             pickerInput(
               "sectormx",
               'Sector',
               selected = "Climate Finance",
               choices = unique(country_matrix$sector),
               #selected = c('SME Finance', 'Insurance', 'Climate Finance'),
               multiple = TRUE)
           ),
           column(
             2,
             pickerInput(
               'componentmx',
               'Component',
               choices = unique(country_matrix$component),
               selected = 'Stakeholder',
               multiple = TRUE,
               options = pickerOptions(
                 actionsBox = TRUE,
                 liveSearch = TRUE,
                 liveSearchPlaceholder = 'Search...',
                 liveSearchNormalize = TRUE,
                 liveSearchStyle = 'contains'
               ),
               width = "100%"
             )
           ),
           column(
             2,
             pickerInput(
               'subcomponentmx',
               'Subcomponent',
               choices = unique(country_matrix$subcomponent),
               selected = 'Quality',
               multiple = TRUE,
               options = pickerOptions(
                 actionsBox = TRUE,
                 liveSearch = TRUE,
                 liveSearchPlaceholder = 'Search...',
                 liveSearchNormalize = TRUE,
                 liveSearchStyle = 'contains'
               ),
               width = "100%"
             )) ,
           column(
             2,
             pickerInput(
               'countrymx',
               'Country',
               choices = countrycmx,
               selected = 'Albania',
               multiple = TRUE,
               options = pickerOptions(
                 actionsBox = TRUE,
                 liveSearch = TRUE,
                 liveSearchPlaceholder = 'Search...',
                 liveSearchNormalize = TRUE,
                 liveSearchStyle = 'contains'
               ),
               width = "100%"
             ))

           #actionButton("update", "Update Data set", class = "btn-primary",style='padding:4px; font-size:120%')
    ),
    
    # Show a plot of the generated distribution
    column(12,
           DTOutput("my_matrix")
           
    )
  )
)


server <- function(input, output, session) {
  
  matrix <- reactive({
    req(input$sectormx, input$componentmx, input$subcomponentmx)
    
    country_matrix %>%
      dplyr::filter(
        sector %in% input$sectormx#,
        #component %in% input$componentmx,
        #subcomponent %in% input$subcomponentmx
      ) %>%
      select(sector,component,subcomponent,input$countrymx)
  })
  
  df <- reactiveVal(NULL)
  
  observe({
    df(matrix())
    })
  
  output$my_matrix  <- renderDT(df(), editable = TRUE, rownames = FALSE)
  
  
  observeEvent(input$my_matrix_cell_edit, {
    #browser()
    info = input$my_matrix_cell_edit
    print(info)
    t <- df()
    t[info$row, info$col+1] <- as.numeric(info$value)
    df(t)
    
  })
  
}

shinyApp(ui = ui, server = server)

Upvotes: 0

YBS
YBS

Reputation: 21349

Try this

country_matrix <- structure(list(industry_group = c("Financial Institutions Group (FIG)", 
                                                    "Financial Institutions Group (FIG)", "Financial Institutions Group (FIG)", 
                                                    "Financial Institutions Group (FIG)", "Financial Institutions Group (FIG)", 
                                                    "Financial Institutions Group (FIG)"), sector = c("Housing Finance", 
                                                                                                      "Climate Finance", "Climate Finance", "Trade Finance", "Housing Finance", 
                                                                                                      "Housing Finance"), component = c("Stakeholder", "Stakeholder", 
                                                                                                                                        "Environment & Social", "Stakeholder", "Environment & Social", 
                                                                                                                                        "Economywide"), subcomponent = c("Access", "Credit: Mitigation", 
                                                                                                                                                                         "Environment", "Environment", "Environment", "Economywide"), 
                                 Afghanistan = c(1, 1, 1, 1, 1, 1), Angola = c(1, 1, 1, 1, 
                                                                               1, 1), Albania = c(1, 1, 1, 1, 1, 1), Argentina = c(1, 1, 
                                                                                                                                   1, 1, 1, 1), Armenia = c(1, 1, 1, 1, 1, 1), `American Samoa` = c(1, 
                                                                                                                                                                                                    1, 1, 1, 1, 1), Azerbaijan = c(1, 1, 1, 1, 1, 1), Burundi = c(1, 
                                                                                                                                                                                                                                                                  1, 1, 1, 1, 1), Benin = c(1, 1, 1, 1, 1, 1), `Burkina Faso` = c(1, 
                                                                                                                                                                                                                                                                                                                                  1, 1, 1, 1, 1), Bangladesh = c(1, 1, 1, 1, 1, 1), Bulgaria = c(1, 
                                                                                                                                                                                                                                                                                                                                                                                                 1, 1, 1, 1, 1), `Bosnia and Herzegovina` = c(1, 1, 1, 1, 
                                                                                                                                                                                                                                                                                                                                                                                                                                              1, 1), Belarus = c(1, 1, 1, 1, 1, 1), Belize = c(1, 1, 1, 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               1, 1, 1), Bolivia = c(1, 1, 1, 1, 1, 1), Brazil = c(1, 1, 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   1, 1, 1, 1), Barbados = c(1, 1, 1, 1, 1, 1), Bhutan = c(1, 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           1, 1, 1, 1, 1), Botswana = c(1, 1, 1, 1, 1, 1), `Central African Republic` = c(1, 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          1, 1, 1, 1, 1) 
), row.names = c(NA, 6L), class = "data.frame")

### 

countrycmx <- names(country_matrix)[5:25]
  
ui <- fluidPage(
  
  # Application title
  #titlePanel("Old Faithful Geyser Data"),
  
  # Sidebar with a slider input for number of bins 
  fluidRow(
    column(12,
           column(
             2,
             pickerInput(
               "sectormx",
               'Sector',
               selected = "Climate Finance",
               choices = unique(country_matrix$sector),
               #selected = c('SME Finance', 'Insurance', 'Climate Finance'),
               multiple = TRUE)
           ),
           column(
             2,
             pickerInput(
               'componentmx',
               'Component',
               choices = unique(country_matrix$component),
               selected = 'Stakeholder',
               multiple = TRUE,
               options = pickerOptions(
                 actionsBox = TRUE,
                 liveSearch = TRUE,
                 liveSearchPlaceholder = 'Search...',
                 liveSearchNormalize = TRUE,
                 liveSearchStyle = 'contains'
               ),
               width = "100%"
             )
           ),
           column(
             2,
             pickerInput(
               'subcomponentmx',
               'Subcomponent',
               choices = unique(country_matrix$subcomponent),
               selected = 'Quality',
               multiple = TRUE,
               options = pickerOptions(
                 actionsBox = TRUE,
                 liveSearch = TRUE,
                 liveSearchPlaceholder = 'Search...',
                 liveSearchNormalize = TRUE,
                 liveSearchStyle = 'contains'
               ),
               width = "100%"
             )) ,
           column(
             2,
             pickerInput(
               'countrymx',
               'Country',
               choices = countrycmx,
               selected = 'Albania',
               multiple = TRUE,
               options = pickerOptions(
                 actionsBox = TRUE,
                 liveSearch = TRUE,
                 liveSearchPlaceholder = 'Search...',
                 liveSearchNormalize = TRUE,
                 liveSearchStyle = 'contains'
               ),
               width = "100%"
             ))
           
           #selectInput("select", "Select country", c('col1', 'col2'), multiple = TRUE),
           #actionButton("update", "Update Data set", class = "btn-primary",style='padding:4px; font-size:120%')
    ),
    
    # Show a plot of the generated distribution
    column(12,
           DTOutput("my_matrix")
           #DTOutput("table")
    )
  )
)


server <- function(input, output, session) {
  
  matrix <- reactive({
    req(input$sectormx, input$componentmx, input$subcomponentmx)
    
    country_matrix %>%
      dplyr::filter(
        sector %in% input$sectormx#,
        #component %in% input$componentmx,
        #subcomponent %in% input$subcomponentmx
      ) %>%
      select(sector,component,subcomponent,input$countrymx)
  })
  
  df <- reactiveValues(data=NULL)
  observe({df$data <- matrix()})
  
  output$my_matrix  <- renderDT(df$data, editable = TRUE, rownames = FALSE)
  
  
  observeEvent(input$my_matrix_cell_edit, {
    info = input$my_matrix1_cell_edit
    str(info)
    i = info$row
    j = info$col + 1
    v = info$value
    df$data[i, j] <<- DT:::coerceValue(v, df$data[i, j])
    
    #replaceData(proxy, x, resetPaging = FALSE, rownames = FALSE)
  })
  
}

shinyApp(ui = ui, server = server)

Upvotes: 1

Related Questions