12

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!

G.D.
  • 170
  • 1
  • 8
  • Why do you want to do this? Can't you subset in a reactive context after you have transformed it as a list? I understand that reactivevalues are not really lists so you can't treat them as such. – InspectorSands Dec 20 '16 at 15:50
  • I want to manipulate the reactive values i.e. update or remove them within observeEvent() function (not sure if it is reactive context or not) – G.D. Dec 20 '16 at 15:59
  • I believe you can't directly delete an element of reactiveValues (I might be wrong). I would suggest an alternative approach, in which you carry out the `values$val1 <- NULL` operation within `observeEvent` and then in your next reactive context you use something like `if (is.null(values$val1))` to evaluate the course of action. Though, again, depends on what you want to achieve. – InspectorSands Dec 20 '16 at 16:03
  • 1
    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. – Slavatron Aug 07 '17 at 19:07
  • @Slavatron did you ever figure out how to do this? I posted a similar question today: https://stackoverflow.com/questions/52261240/shiny-how-to-initialize-empty-reactivevalues-with-an-actionbutton (basically same question as you, but deleting ALL entries inside a `reactiveValues`). Lemme know! – Ray Sep 11 '18 at 01:04

2 Answers2

4

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)
    })
  }))
bio.rf
  • 41
  • 2
3

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