Reputation: 59
So I am using mpg dataset to practice my R-shiny skills, but I encountered a problem.
I want to write a app which I could choose different variables to make graph, if it involves at least one discrete variable, then I draw a geom_boxplot, else, I will just draw a geom_point.
Now I want to add a slider to filter numeric inputs, but how?
My ui.R looks like this:
library(shiny)
shinyUI(fluidPage(
# Application title
titlePanel("Old Faithful Geyser Data"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
selectInput(inputId = "var1",
label = "Choose x variable",
choices =
names(mpg)
),
selectInput(inputId = "var2",
label = "Choose y variable",
choices =
names(mpg))
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
)
)
))
And My server.R looks like this:
server <- function(input,output){
output$distPlot <- renderPlot({
# browser()
if(typeof(mpg[[input$var1]]) == "character")
{
ggplot(mpg) +
xlab(input$var1) +
ylab(input$var2) +
ggtitle(paste("Plot", input$var1, "vs", input$var2)) +
geom_boxplot(mapping =
aes_string(x = input$var1,
y = input$var2))
}
else
{
ggplot(mpg) +
xlab(input$var1) +
ylab(input$var2) +
ggtitle(paste("Plot", input$var1, "vs", input$var2)) +
geom_point(mapping =
aes_string(x = input$var1,
y = input$var2))
}
})
}
Now, how could I add a slider to filter numeric input?
I am a new learner, please help me. Thank you very much
Upvotes: 1
Views: 1137
Reputation: 783
I'm sorry that I don't have time to flesh out this demo into a better example but hopefully this will show you the methodology:
library(shiny)
library(ggplot2)
library(magrittr)
ui <- fluidPage(
# Application title
titlePanel("Optional Numeric Slider Demo"),
sidebarLayout(
sidebarPanel(
selectInput(inputId = "var1",
label = "Choose x variable",
choices =
names(mpg)
),
uiOutput('Var1Slider'),
br(),
selectInput(inputId = "var2",
label = "Choose y variable",
choices =
names(mpg)[sapply(mpg,class)=="character"])
),
mainPanel(
plotOutput("distPlot")
)
)
)
server <- function(input,output){
output$distPlot <- renderPlot({
if(typeof(mpg[[input$var1]]) == "character")
{
ggplot(mpg) +
xlab(input$var1) +
ylab(input$var2) +
ggtitle(paste("Plot", input$var1, "vs", input$var2)) +
geom_boxplot(mapping =
aes_string(x = input$var1,
y = input$var2))
}
else
{
mpg %>%
dplyr::filter(get(input$var1)>input$Var1Slide[1]) %>%
dplyr::filter(get(input$var1)<input$Var1Slide[2]) %>%
ggplot() +
xlab(input$var1) +
ylab(input$var2) +
ggtitle(paste("Plot", input$var1, "vs", input$var2)) +
geom_point(mapping =
aes_string(x = input$var1,
y = input$var2))
}
})
output$Var1Slider <- renderUI({
if(typeof(mpg[[input$var1]]) == "character"){
return(NULL)
}else{
sliderInput('Var1Slide',
label=paste("selected:",input$var1),
min=min(mpg[[input$var1]]),
max=max(mpg[[input$var1]]),
value=c(min(mpg[[input$var1]]),max(mpg[[input$var1]])),
step = 1)}
})
}
# Run the application
shinyApp(ui = ui, server = server)
The key points are the use of renderUI
and uiOutput
to move computation to the server side. I've also added a line to the numeric graph code to show how to use the input (even if the edit is nonsensical at the moment). Let me know if anything is unclear.
EDIT:I've changed this example so that the slider values actually filter the data going into the plot.
Upvotes: 1