Reputation: 112
I am having problems using conditional statements in Shiny. I want the user select number of variable. If choose 1 variable then plot chart of 1 variable (ex density plot), if choose 2 variable then plot chart of 2 variables (ex scatter plot). I have tried a few ways, but the output is not as my expected. How can i use if else statement in Shiny server? Tks
UI
df <- mtcars
ui <- fluidPage(
h1("My first app",
style = 'color: green;
font-style: italic'),
hr(),
fluidRow(
sidebarPanel(
radioButtons(inputId = "number",
label = "Select number of variable",
choices = c("1 variable" = 1,
"2 variable" = 2)),
selectInput(inputId = "x",
label = "Variable 1",
choices = names(df)),
conditionalPanel(
condition = "input.number == 2",
selectInput(inputId = "y",
label = "Variable 2",
choices = names(df))
)
),
column(8, plotOutput("plot"))
),
hr(),
plotOutput("plot") )
Server
server <- function(input, output, session){
observeEvent(input$x,
{updateSelectInput(session,
inputId = "y",
label = "Variable 2",
choices = names(df)[names(df) != input$x])
})
data <- reactive({
if(input$number == 1){
data <- df %>%
select(input$x)
} else {
data <- df %>%
select(input$x, input$y)
}
})
output$plot <- renderPlot({
if(input$number == 1){
ggplot(data = data(),
x = get(input$x))+
geom_density()
} else {
ggplot(data = data,
x = get(input$x),
y = get(input$y)) +
geom_point()
}
})
}
shinyApp(ui = ui, server = server)
Upvotes: 3
Views: 1398
Reputation: 388982
You can try the following code -
plotOutput("plot")
was mentioned twice, removed it to include it only once.reactive
, handle it in the plot code itself..data
to refer column names in ggplot code.library(shiny)
library(ggplot2)
df <- mtcars
ui <- fluidPage(
h1("My first app",
style = 'color: green;
font-style: italic'),
hr(),
fluidRow(
sidebarPanel(
radioButtons(inputId = "number",
label = "Select number of variable",
choices = c("1 variable" = 1,
"2 variable" = 2)),
selectInput(inputId = "x",
label = "Variable 1",
choices = names(df)),
conditionalPanel(
condition = "input.number == 2",
selectInput(inputId = "y",
label = "Variable 2",
choices = names(df))
)
),
column(8, plotOutput("plot"))
)
)
server <- function(input, output, session){
data <- reactive({
df
})
observeEvent(input$x,
{updateSelectInput(session,
inputId = "y",
label = "Variable 2",
choices = names(df)[names(df) != input$x])
})
output$plot <- renderPlot({
if(input$number == 1){
plot <- ggplot(data = data(), aes(x = .data[[input$x]])) + geom_density()
} else {
plot <- ggplot(data = data(),
aes(x = .data[[input$x]], y = .data[[input$y]])) +
geom_point()
}
plot
})
}
shinyApp(ui = ui, server = server)
Upvotes: 3
Reputation: 41220
You could use aes_string
.
Another very important point is never to use the same output twice in UI
:
df <- mtcars
library(ggplot2)
library(dplyr)
ui <- fluidPage(
h1("My first app",
style = 'color: green;
font-style: italic'),
hr(),
fluidRow(
sidebarPanel(
radioButtons(inputId = "number",
label = "Select number of variable",
choices = c("1 variable" = 1,
"2 variable" = 2)),
selectInput(inputId = "x",
label = "Variable 1",
choices = names(df)),
conditionalPanel(
condition = "input.number == 2",
selectInput(inputId = "y",
label = "Variable 2",
choices = names(df))
)
),
column(8, plotOutput("plot"))
),
hr()
# Never use output twice : the UI won't work!
#plotOutput("plot")
)
server <- function(input, output, session){
observeEvent(input$x,
{updateSelectInput(session,
inputId = "y",
label = "Variable 2",
choices = names(df)[names(df) != input$x])
})
data <- reactive({
if(input$number == 1){
data <- df %>%
select(input$x)
} else {
data <- df %>%
select(input$x, input$y)
}
})
output$plot <- renderPlot({
cat(input$x)
if(input$number == 1){
ggplot(data = data())+
geom_density(aes_string(x=input$x))
} else {
ggplot(data = data()) +
geom_point(aes_string(x=input$x,y=input$y))
}
})
}
shinyApp(ui = ui, server = server)
Upvotes: 3