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")
)
)
)
source to share
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")
)
)
))
source to share