R shiny ERROR: object of type "closure" is not a subset

I am using the following code and I always get this subset of the error. What am I multiplying and where am I wrong. It must be some basic input code that I have modified and that works at some point and I see no error.

thank

server.R

library(shiny)

# Define a server for the Shiny app
shinyServer(function(input, output) {

  # Filter data based on selections
  output$table <- renderDataTable({
    data <- read.table("my.csv", sep =',', header =TRUE)
    if (input$shortdesc != "All"){
      data <- data[data$ShortDescription == input$shortdesc,]
    }
    if (input$taken != "All"){
      data <- data[data$Taken == input$taken,]
    }
    if (input$location != "All"){
      data <- data[data$Location == input$location,]
    }
    data
  })

})

      

ui.R

library(shiny)
# Define the overall UI

shinyUI(
  fluidPage(
    titlePanel("My Items"),

    # Create a new Row in the UI for selectInputs
    fluidRow(
      column(4, 
             selectInput("man", 
                         "What:", 
                         c("All", 
                           unique(as.character(data$ShortDescription))))
      ),
      column(4, 
             selectInput("trans", 
                         "Where:", 
                         c("All", 
                           unique(as.character(data$Location))))
      ),
      column(4, 
             selectInput("cyl", 
                         "Who:", 
                         c("All", 
                           unique(as.character(data$Taken))))
      )        
    ),
    # Create a new row for the table.
    fluidRow(
      dataTableOutput(outputId="table")
    )    
  )  
)

      

Update:

Why does this example work (see below) and as soon as I change it to my.csv does it break? If "data" is a build function, wouldn't that also clash with the example below? Sorry for the misunderstanding, but this puzzles me.

server.R

library(shiny)

# Load the ggplot2 package which provides
# the 'mpg' dataset.
library(ggplot2)

# Define a server for the Shiny app
shinyServer(function(input, output) {

  # Filter data based on selections
  output$table <- renderDataTable({
    data <- mpg
    if (input$man != "All"){
      data <- data[data$manufacturer == input$man,]
    }
    if (input$cyl != "All"){
      data <- data[data$cyl == input$cyl,]
    }
    if (input$trans != "All"){
      data <- data[data$trans == input$trans,]
    }
    data
  })

})

      

ui.R.

library(shiny)

# Load the ggplot2 package which provides
# the 'mpg' dataset.
library(ggplot2)

# Define the overall UI
shinyUI(
  fluidPage(
    titlePanel("Basic DataTable"),

    # Create a new Row in the UI for selectInputs
    fluidRow(
      column(4, 
          selectInput("man", 
                      "Manufacturer:", 
                      c("All", 
                        unique(as.character(mpg$manufacturer))))
      ),
      column(4, 
          selectInput("trans", 
                      "Transmission:", 
                      c("All", 
                        unique(as.character(mpg$trans))))
      ),
      column(4, 
          selectInput("cyl", 
                      "Cylinders:", 
                      c("All", 
                        unique(as.character(mpg$cyl))))
      )        
    ),
    # Create a new row for the table.
    fluidRow(
      dataTableOutput(outputId="table")
    )    
  )  
)

      

+1


source to share


1 answer


Expanding @Roland comment: namespace collision occurs. There is a function in R's base data

, so if R cannot find an object data

in the current environment, the function data

refers to the global environment. In your particular case, this is due to the fact that ui.R

both server.R

are in different environments, and, in addition, the individual function bodies have their own environments. Thus, data

in fluidRow(...)

does not refer to data

from output$table

. You need to pass arguments and / or dynamically build the user interface using functions. See an example here .

Update updated question:

Replacing data

with mpg

in ui.R

fixes the problem because it mpg

is defined as a dataset in the global environment (this is a side effect library(ggplot2)

). Thus, it is mpg

(almost) always available and has the required properties. For a fairer comparison, replace mpg

with ui.R

with data

, which should return the old problem, because data

in the global environment refers to a function, not the data frame you are trying to manipulate.

Super Update with a more general solution to dynamically define and load select items for each dataset:

The server code goes through all the columns of the selected data frame and dynamically generates a select box for each column that is of non-double type. (Singularity and equality with doubles just pose problems.) This avoids scoping problems because UI elements are created in server.R

after the call to the reactive function that loads the data.



server.R

library(shiny)
library(ggplot2)
# Define a server for the Shiny app
shinyServer(function(input, output) {

  get.data <- reactive({
    switch(input$dataset,
           "rock" = rock,
           "pressure" = pressure,
           "cars" = cars,
           "mpg" = mpg,
           "mtcars" = mtcars,
           "diamonds" = diamonds)
  })

  # Filter my.data based on selections
  output$table <- renderDataTable({
    my.data <- get.data()
    for(n in names(my.data)){
        # avoid too many cases ... 
        # unique() with double is just asking for trouble
        if(typeof(my.data[,n]) != "double"){ 
            val <- eval(parse(text=paste0("input$",n)))
            print(val)
            if(val != "All"){
                my.data <- eval(parse(text=paste0("subset(my.data,",n,"==",val,")")))
            }
        }
    }
    my.data
  })

  output$dyn.ui <- renderUI({
      my.data <- get.data()
      sel <- NULL
      for(n in names(my.data)){
          # avoid too many cases ... 
          # unique() with double is just asking for trouble
          if(typeof(my.data[,n]) != "double"){ 
              sel <- c(sel,
                   selectInput(n, n, choices=c("All",unique(my.data[,n])))
                   )
          }
      }
      sel
  })

})

      

ui.R

library(shiny)

# Define the overall UI

shinyUI(fluidPage(
    titlePanel("Displaying tables dynamically with renderUI() and eval()"),

    sidebarLayout(
        sidebarPanel(h2("Selection"),
                     selectInput("dataset", "Dataset", c("rock", "pressure", "cars","mtcars","diamonds")),
                     # Create a new Row in the UI for selectInputs
                     uiOutput("dyn.ui")

        )
        ,mainPanel(h2("Data"),
           dataTableOutput(outputId="table")       
        )
    )


))

      

+9


source







All Articles