I'm trying to build a simply R Shiny app that displays a bar chart with both axes as interactive elements. I'll demonstrate what I've done with the built in flights dataset.
I'm able to build a static bar chart, but only get errors when interactive. I've tried colnames(data), names(data), and aes_string in the server function. I think the issue is that in the ggplot aes the x label is read in as string but after_stat(count) isn't. Unfortunately I can't find any similar examples on the internet.
Any ideas how to resolve this? Thanks
# load packages
library(dplyr)
library(tidyr)
library(shiny)
library(ggplot2)
# data
library(nycflights13)
data = flights %>% select(carrier, origin, dest)
# desired bar chart
ggplot(data, aes(x=carrier, y=after_stat(count)))
geom_bar(aes(fill = origin), position = "dodge")
ui <- fluidPage(
# sidebar
sidebarLayout(
selectInput(inputId = "xvar",
label = "X-axis variable",
choices = colnames(data),
#choices = names(data),
selected = "carrier"
),
selectInput(inputId = "yvar",
label = "Y-axis variable",
choices = colnames(data),
#choices = names(data),
selected = "origin"
)
),
# main plot
mainPanel(
plotOutput("id_main_plot")
)
)
# server logic to draw histogram
server <- function(input, output) {
output$id_main_plot <- renderPlot({
# Render bar chart
ggplot(data = data,
aes(x = input$xvar,
y = after_stat(count)
)
)
geom_bar(aes(fill = input$yvar),
position = "dodge"
)
})
}
# create Shiny app
shinyApp(ui, server)
CodePudding user response:
The issue is that input$xvar
and input$yvar
are just character strings. When you map these on aesehtics in ggplot2 they will be treated as constants. To tell ggplot2
that these character strings are names of columns in your dataset you could use the so-called .data
pronoun. For more on the .data
pro-noun in the context of ggplot2 and shiny see e.g. this example in Mastering Shiny
library(shiny)
library(dplyr)
library(ggplot2)
library(nycflights13)
data <- flights %>% select(carrier, origin, dest)
ui <- fluidPage(
sidebarLayout(
selectInput(
inputId = "xvar",
label = "X-axis variable",
choices = colnames(data),
selected = "carrier"
),
selectInput(
inputId = "yvar",
label = "Y-axis variable",
choices = colnames(data),
selected = "origin"
)
),
mainPanel(
plotOutput("id_main_plot")
)
)
server <- function(input, output) {
output$id_main_plot <- renderPlot({
ggplot(
data = data,
aes(
x = .data[[input$xvar]],
y = after_stat(count)
)
)
geom_bar(aes(fill = .data[[input$yvar]]),
position = "dodge"
)
})
}
# create Shiny app
shinyApp(ui, server)
#>
#> Listening on http://127.0.0.1:3217