Home > front end >  Trouble with Reactive Dataframes in Shiny
Trouble with Reactive Dataframes in Shiny

Time:04-20

Here's the Screenshot

The error is object of type 'closure' is not subsettable. While many questions (and answers) regarding this error exist, I am yet to find any explaining the behaviour demonstrated above.

Why does this happen?

The normal (script-equivalent) works as expected.

datExpr <- as.data.frame(iris)
n = 50
datExpr0 <- datExpr[1:n, ]
datExpr0
keepSamples = 10
datExpr <- datExpr0[keepSamples,]
datExpr

Is there a way to achieve what the normal script does in the shiny app?

CodePudding user response:

The issue is that you have both a dataframe and a reactive in your app called datExpr. Simply rename one of both (I decided for the reactive).

EDIT There is of course nothing special about that in shiny.

A simple example to illustrate the issue:

datExpr <- iris
datExpr <- function() {}
datExpr[1:2]
#> Error in datExpr[1:2]: object of type 'closure' is not subsettable

And you see that we get the famous object of type 'closure' is not subsettable error too. The general issue or lesson is that in R you can't have two different objects with the same name at the same time.

# This is a Shiny web application. 

library(shiny)

# UI for application
ui <- fluidPage(
  
  # Application title
  titlePanel("A Problematic App - Part 2"),
  
  # Sidebar with two slider inputs
  sidebarLayout(
    sidebarPanel(
      sliderInput(
        "NoOfSamples",
        label = "Sample Size",
        value = 100,
        min = 10,
        max = 150,
        step = 10,
        width = "40%"
      ),
      sliderInput(
        "KeepSamples",
        label = "Samples to Keep",
        value = 50,
        min = 10,
        max = 150,
        step = 10,
        width = "40%"
      )
    ),
    
    # Shows the resulting table
    mainPanel(
      tableOutput("table1"),
      tableOutput("table2")
    )
  )
)

# Server logic
server <- function(input, output) {
  
  # Using the iris dataset
  datExpr <- as.data.frame(iris)
  
  n = reactive({
    input$NoOfSamples
  })
  datExpr0 <- reactive({
    datExpr[1:n(), ]
  })
  output$table1 <- renderTable({
    datExpr0()
  })
  # Displays the first table correctly if the rest is commented out
  keepSamples = reactive({
    input$KeepSamples
  })
  datExpr1 <- reactive({
    datExpr0()[keepSamples(),]
  })
  output$table2 <- renderTable({
    datExpr1()
  })
}

# Run the application 
shinyApp(ui = ui, server = server)
#> 
#> Listening on http://127.0.0.1:3648

  • Related