I'm trying to plot a continous variable (y) versus another one (x), and color the data points in the plot depending on a third categorical variable (z). To select these three variables I use a selectInput function, but to select the possible categories (levels(input$z)) I want to plot, I use a uiOutput function. I'm trying to subset the selected levels in a filtered dataframe (dataf) but this is not working. Some reactive expressions are working, but I rolled back the code with the subsetting because when I use ( dataf <- filter(data(), input$z %in% input$show_levels)) in the renderPlot function I don't get any data point plotted.
I have prepared a simplified version of what I need using the diamonds dataset. For example, I would need my shinyApp to plot prize vs carats, with the points colored depending on the cut, and being able to represent only the ones with a certain cut (for instance cut == c("Fair", "Good").)
library(shiny)
library(ggplot2)
library(RColorBrewer)
library(dplyr)
cont_vars <- c("price", "carat", "x", "y", "z", "depth", "table")
discr_vars <- c("cut", "color", "clarity")
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Analysis of 'diamonds' dataset"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
# Select variable for y-axis
selectInput(inputId = "y",
label = "Y-axis:",
choices = cont_vars,
selected = cont_vars[1]),
# Select variable for x-axis
selectInput(inputId = "x",
label = "X-axis:",
choices = cont_vars,
selected = cont_vars[2]),
# Select variable for color
selectInput(inputId = "z",
label = "Z-axis:",
choices = discr_vars,
selected = discr_vars[1]),
# Select level/s to show for the z category
uiOutput("selected_z")
),
# Show the plot
mainPanel(
plotOutput("scatterplot")
)
)
)
# Define server logic required to draw a scatterplot
server <- function(input, output) {
# Show levels for the discrete variable selected in input$selected_z
output$selected_z <- renderUI({
checkboxGroupInput(inputId = "show_levels",
label = "Select category/ies to represent:",
choices = choices_z(),
selected = choices_z())
})
choices_z <- reactive({
df <- select(diamonds, input$z)
return(levels(df[[1]]))
})
output$scatterplot <- renderPlot({
# generate df based on inputs selected
data <- select(diamonds, input$x, input$y, input$z)
# dataf <- filter(data(), input$z %in% input$show_levels)
ggplot(data, aes_string(x = input$x, y = input$y,
color = input$z)) +
geom_point(size = 4) +
scale_color_brewer(palette = "Paired") +
theme_light()
})
}
# Run the application
shinyApp(ui = ui, server = server)
I expected to select the input$show_levels categorical variables (levels) I'm interested in the checkboxGroupInput (input$showlevels), and show only the points in the seleceted categories in the scatterplot. Right now I got the checkboxGroupInput function for the levels to appear (see image below), but I'm afraid it's not connected to the server, and all the levels of input$z are being plotted. how the shinyApp is now
It looks like you had it just about set when you tried to filter the data (your commented line starting with dataf
). You need to get filter()
to recognize that you want it to use the column represented by input$z
, not to use the actual value input$z
(which is "cut"
). If you update renderPlot
so that the data are filtered like this
data <-
select(diamonds, input$x, input$y, input$z) %>%
filter(!!(as.name(input$z)) %in% input$show_levels)
then the app should work as you expected. This answer has more details about why/how to deal with passing shiny inputs to dplyr functions.