How to delete element from reactiveValues in shiny?

3.9k views Asked by At

How to delete element from reactiveValues()

For example, when I run the code:

library(shiny)

runApp(list(
  ui=tableOutput("table1"),
  server=function(input, output, session) {
    values <- reactiveValues(val1 = 1, val2 =2, val3 = 3)
    values$val1 <- NULL

    output$table1 <- renderPrint(reactiveValuesToList( values) )
  }))

The output is:

$val1 NULL $val2 [1] 2 $val3 [1] 3

Instead of:

$val2 [1] 2 $val3 [1] 3

Thank you!

2

There are 2 answers

0
Zygmunt Zawadzki On

I'll try to addres this:

I would like to delete elements from a reactiveValues object because I am using it to store user-defined list objects that can be quite large individually. My concern is that if the user creates too many such objects in a single session it will cause the app to crash due to insufficient memory.

When you assign NULL to the value R will remove the element from memory. See the app below - when you click delete button the memory is released:

library(shiny)


ui <- fluidPage(
    mainPanel(
      actionButton("delete", "delete"),
      verbatimTextOutput("table1")
    )
  )
)

runApp(list(
  ui=ui,
  server=function(input, output, session) {
    values <- reactiveValues(val1 = rnorm(1e7), val2 =2, val3 = 3)

    observeEvent(input$delete,{
      values$val1 <- NULL
    })

    output$table1 <- renderPrint({
      res <- capture.output(gc())
      cat(res, sep = "\n")
      x <- reactiveValuesToList(values)
      length(x)
    })
  }))

The two images below show you the state before clicking the delete, and after -> note that the value used by R has changed.

Those missing 80mb is the size of the val1 vector.

pryr::object_size(rnorm(1e7))
# 80 MB

Before click After click

0
bio.rf On

If you still want to use the assignment to NULL to remove values, you can assign the reactive value to be a list. See below for a simple modification to Zygmunt Zawadzki's answer. Then operate on the list in the usual R way to reflect the changes in your data.

library(shiny)


ui <- fluidPage(
    mainPanel(
      actionButton("delete", "delete"),
      verbatimTextOutput("table1")
    )
  )
)

runApp(list(
  ui=ui,
  server=function(input, output, session) {
    values <- reactiveValues(data=list(val1 = rnorm(1e7), val2 =2, val3 = 3))

    observeEvent(input$delete,{
      values$data$val1 <- NULL
    })

    output$table1 <- renderPrint({
      res <- capture.output(gc())
      cat(res, sep = "\n")
      # No reactiveValuesToList needed
      # x <- reactiveValuesToList(values)
      length(values$data)
    })
  }))