12
votes

I'm trying to build a Shiny app that subsets a data frame (to only include rows where a categorical variable matches the user-select input from the UI) before the data is processed in Server and then visualized in the UI. I've tried several different methods but I keep getting errors, e.g. "object of type 'closure' is not subsettable"

Then when I try to cast the reactive user input with

target <- toString(reactive({input$value}))

I get the following error:

"Error in as.vector(x, "character") : cannot coerce type 'closure' to vector of type 'character'"

Any ideas? I think there is something conceptual that I'm missing. Here is my code:

#Server
shinyUI(pageWithSidebar(

headerPanel("Pricing Analysis Tool"),

sidebarPanel(
selectInput("fruit", "Select fruit:", 
            choices = c(inventory), selected = "banana", multiple = FALSE),
numericInput("delta", "Price Change (%):", 10),
submitButton("Run Simulation")),

mainPanel(
plotOutput("PricePlot")
)))


#server
shinyServer(function(input, output, session) {

target_inventory <- reactive({inventory$product == input$fruit})
...

})

Once my inventory data is subset to only include the product I'm evaluating then I will use renderPlot to generate graphs. I'm getting hung up on subsetting based on a user input. Is there some other method I should use to dynamically subset the larger data set based on a user input?

Thanks so much for your help, Noah

Update: I was able to successfully subset my data based on variable user inputs and then manipulate the subset and visualize it using this code in my server file (thank you, nivangio, for posting your code which I used as a template on R-blogger: http://www.r-bloggers.com/dashboards-in-r-with-shiny-and-googlevis/)

target_inventory <- reactive({
    a <- subset(inventory, inventory$product %in% input$fruit)
    a <- droplevels(a)
return(a)
})

Once the subset was created, I was able to use it in dynamic graphs by referencing it as target_inventory()

1
Just reverse the order and do target <- reactive({toString(input$value)})Ramnath
Thanks for the quick reply, @Ramnath! Assuming the input selected in the UI were "banana", would you expect print(target) to return "banana"? I'm still not having luck...noah_r_user
You will have to post some code for us to understand the context better. Otherwise you will see a lot of answers based on speculation of your needs.Ramnath
Thanks @Ramnath, I'm new to Stackoverflow -- still learning the etiquette :-) just added my code to the post.noah_r_user
When you use target_inventory to subset your data, since it is a reactive object and hence a closure, you must include parentheses: inventory[target_inventory(), ]. However, without fully a reproducible example, it's just a guess.BenBarnes

1 Answers

11
votes

I had the same issue and spent a couple of hours trying to figure it out. Once you have assigned the reactive object, you need to use target_inventory() in order to refer to it (as BenBarnes mentioned in the comment section).

Here is a MWE (minimum working example)

ui.R

#ui
library(shiny)

shinyUI(fluidPage(
  #User dropbox
  selectInput("state", "Choose state", choices=c("MA", "CA", "NY"))
  #Print table to UI
  ,tableOutput("table1")
))

server.r

 #server
library(shiny)

shinyServer(function(input,output){

  category <- c("MA", "CA", "NY")
  population <- c(3,8,4)

  df <- data.frame(category,population)

  df_subset <- reactive({
    a <- subset(df, category == input$state)
    return(a)
  })

  output$table1 <- renderTable(df_subset()) #Note how df_subset() was used and not df_subset


})